diff --git a/CONTEXT.md b/CONTEXT.md index 9e300788..e525de5a 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -13,22 +13,24 @@ - **Fold preparation**: building the object to model for one prediction job and its output directory, including AlphaPulldown-style naming and feature-metadata copying. Shared by the single-fold command and the resident batch so the two cannot diverge. -- **Feature request**: one named sequence, of a stated molecule type, requiring an AlphaFold 3 feature artifact. +- **Feature request**: one named sequence, of a stated molecule type, requiring a feature artifact. - **Molecule type**: whether a feature request is a protein or an RNA chain. It decides which databases are searched, whether a paired MSA exists at all, and which AlphaFold 3 - chain the finalized artifact carries. DNA has no MSA and is not handled by this path. + chain the finalized artifact carries. RNA is AlphaFold 3 only, and DNA has no MSA and + is not handled by this path. - **Feature batch**: an ordered collection of feature requests handled as one operation. - **MSA batch**: the GPU stage that searches MMseqs2 and durably publishes one reusable MSA bundle per feature request. -- **Feature finalization**: the CPU stage that reads an MSA bundle, performs native AF3 template search, and publishes the standard AF3 feature artifact. -- **MSA bundle**: an atomic intermediate JSON containing one sequence, merged unpaired A3M, paired A3M, and complete MMseqs/database provenance. +- **Feature finalization**: the CPU stage that reads an MSA bundle, performs the backend's native template search (AF3's, or AF2's hmmsearch/hhsearch), and publishes that backend's standard feature artifact. +- **MSA bundle**: an atomic intermediate JSON containing one sequence, merged unpaired A3M, paired A3M, how many unpaired rows each database contributed, and complete MMseqs/database provenance. Its A3Ms carry both full database headers and insertions. +- **Two-pass format**: formatting one MMseqs2 search result twice and joining the passes row by row, because the format with full headers drops insertions and the format with insertions drops the headers. - **Database identifier**: the caller-supplied immutable identity of one MMseqs2 database build; cache validity depends on it, not only its filesystem path. -- **Feature artifact**: the standard AlphaFold 3 JSON (optionally LZMA-compressed) produced for one feature request. +- **Feature artifact**: the standard features one backend consumes for one feature request: an AlphaFold 3 JSON, or an AlphaFold 2 MonomericObject pickle (either optionally LZMA-compressed). - **MSA cache hit**: an existing MSA bundle whose sequence, MMseqs2 executable version, search settings, and database identifiers match the request. -- **Feature cache hit**: an existing feature artifact whose MSA provenance, maximum template date, PDB seqres identity, and mmCIF identity match the request. +- **Feature cache hit**: an existing feature artifact whose MSA provenance, maximum template date, PDB seqres identity, and mmCIF identity match the request (for AlphaFold 2, also the template searcher). - **Recoverable failure**: a failure isolated to one sequence; remaining requests continue and the batch reports a nonzero summary after writing successful artifacts. - **Database role**: whether a configured MMseqs2 database supplies unpaired hits (uniref90, mgnify, small_bfd, merged into one MSA) or paired hits (uniprot, whose - UniProt taxon headers let AlphaFold 3 pair chains by species). Roles are named, not + UniProt taxon headers let AlphaFold pair chains by species). Roles are named, not inferred from a position in the configured list. - **RNA database set**: the three nucleotide databases AlphaFold 3 merges into one unpaired RNA MSA (rfam, rnacentral, nt_rna). All unpaired - AlphaFold 3 never pairs diff --git a/README.md b/README.md index 6dbf591f..f6b0835d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ### Quick install (recommended) ```bash -curl -O https://raw.githubusercontent.com/KosinskiLab/AlphaPulldownSnakemake/2.8.0/install.sh +curl -O https://raw.githubusercontent.com/KosinskiLab/AlphaPulldownSnakemake/2.9.0/install.sh bash install.sh conda activate snake cd AlphaPulldownSnakemake @@ -25,7 +25,7 @@ Useful options: | Option | Meaning | | --- | --- | | `-d, --dest DIR` | working directory to deploy into (default `AlphaPulldownSnakemake`) | -| `-v, --version TAG` | workflow version to deploy (default `2.8.0`) | +| `-v, --version TAG` | workflow version to deploy (default `2.9.0`) | | `-i, --image-dir DIR` | shared container image directory | | `-n, --env-name NAME` | conda environment name (default `snake`) | | `--no-pull` | skip container pre-fetch (Snakemake will fetch on first run) | @@ -43,7 +43,7 @@ Create and activate the conda environment: ```bash conda env create \ -n snake \ - -f https://raw.githubusercontent.com/KosinskiLab/AlphaPulldownSnakemake/2.8.0/workflow/envs/alphapulldown.yaml + -f https://raw.githubusercontent.com/KosinskiLab/AlphaPulldownSnakemake/2.9.0/workflow/envs/alphapulldown.yaml conda activate snake ``` @@ -55,7 +55,7 @@ Then deploy the workflow into a new processing directory for your project: snakedeploy deploy-workflow \ https://github.com/KosinskiLab/AlphaPulldownSnakemake \ AlphaPulldownSnakemake \ - --tag 2.8.0 + --tag 2.9.0 cd AlphaPulldownSnakemake ``` @@ -71,12 +71,13 @@ images are still shared across projects. See | section | what it holds | | --- | --- | -| **REQUIRED** | inputs, output directory, databases, weights, prediction container | -| **COMMON** | features, backend flags, analysis, batching, SLURM partition | -| **ADVANCED** | memory sizing, length filtering, GPU routing, spilling, CPU partitions | +| **REQUIRED** | inputs, output directory, databases, weights, matching backend settings, SLURM partitions | +| **COMMON** | precomputed features, feature-only runs, analysis, duplicate complexes | +| **ADVANCED** | batching, resource limits, GPU selection, local MMseqs2, detailed report options | -Each key carries a one-line comment naming the section below that documents it in full. -A first run normally only needs the REQUIRED section. +The comments explain each group and point to the relevant section below. A first run +normally only needs REQUIRED. Desktop runs ignore the SLURM settings. Local MMseqs2 +is off by default; its complete configuration is kept together under ADVANCED. ### Setup protein folding jobs @@ -104,24 +105,25 @@ You can also specify: - **Combinations**: `Q8I2G6:2:1-100+Q8I5K4` (dimer of residues 1-100 plus another protein) - **Copies plus discontinuous regions**: `Q8I2G6:2:1-100:150-200+Q8I5K4` -The same copy/range syntax also works with AlphaFold 3 JSON features -(`--data_pipeline: alphafold3`). Examples: +The same copy/range syntax also works when the workflow generates AlphaFold 3 +JSON features (`--data_pipeline: alphafold3`). Examples: - `Q8I2G6_af3_input.json:1-100` - `Q8I2G6_af3_input.json:1-100:150-200` - `Q8I2G6_af3_input.json:2:1-100:150-200+Q8I5K4_af3_input.json` -When a workflow or wrapper maps a logical token such as `Q8I2G6:1-100:150-200` -to `Q8I2G6_af3_input.json:1-100:150-200`, AlphaPulldown preserves the region -selection and keeps the AF3 JSON feature input as one discontinuous polymer -chain with preserved residue-number gaps, so chopped regions stay intra-chain -and template contacts between retained fragments are not masked as inter-chain -interactions. The original residue IDs are written to the mmCIF author-numbering -fields (`auth_seq_id` and `pdbx_PDB_ins_code`); overlapping IDs are disambiguated -with insertion codes such as `2A`, `2B`, and so on. -This syntax is parsed by the shared `alphapulldown-input-parser` package used by -both AlphaPulldown and AlphaPulldownSnakemake; make sure the execution -environment carries `alphapulldown-input-parser>=0.5.1`. +In that mode the Snakefile rewrites logical inputs such as +`Q8I2G6:1-100:150-200` to the corresponding +`Q8I2G6_af3_input.json:1-100:150-200` feature reference automatically. +AlphaPulldown preserves those discontinuous regions as one gapped polymer +chain with preserved residue-number gaps. +This keeps retained fragments intra-chain, so template contacts between those +fragments are not masked as inter-chain interactions. +The original residue IDs are written to the mmCIF author-numbering fields +(`auth_seq_id` and `pdbx_PDB_ins_code`); overlapping IDs are disambiguated with +insertion codes such as `2A`, `2B`, and so on. +Make sure the prediction container or runtime environment includes a matching +AlphaPulldown build together with `alphapulldown-input-parser>=0.5.1`. @@ -136,7 +138,7 @@ input_files: ### Setting up databases -If you do not already have the AlphaFold databases, `scripts/setup_databases.sh` +If you do not already have the AlphaFold databases, `scripts/setup_databases.sh` from AlphaPulldown fetches them and builds the MMseqs2 versions: ```bash @@ -335,18 +337,18 @@ prediction_container: "/path/to/images/alphafold3-2.5.0.sif" ### GPU compatibility The containers carry their own CUDA runtime (pip `nvidia-*` wheels), so GPU support depends on the -image tag, not on the driver installed on the node. Releases 2.5.0 and newer run on every GPU in the -EMBL cluster, with both AlphaFold 2 and AlphaFold 3: - -- RTX 3090, 24 GB, sm_86 (`gpu21-22`, `gpu29-37`) -- A100, 40 GB, sm_80 (`gpu25-28`) -- A40, 48 GB, sm_86 (`sb03-05` to `sb03-20`) -- L40S, 48 GB, sm_89 (`gpu40-48`) -- H100, 80 GB, sm_90 (`gpu38-39`, and `hgx2-3` in `gpu-training`) -- H200, 141 GB, sm_90 (`hgx4-5` in `gpu-training`) -- B200, 180 GB, sm_100 (`bgx1` in `gpu-training`) -- RTX PRO 4500 Blackwell, 16 GB MIG slices, sm_120 (`gpu60-68`) -- RTX PRO 6000 Blackwell, 96 GB, sm_120 (`gpu51-53`) +image tag, not on the driver installed on the node. Releases 2.5.0 and newer have been tested on +the following GPUs, with both AlphaFold 2 and AlphaFold 3: + +- RTX 3090, 24 GB, sm_86 +- A100, 40 GB, sm_80 +- A40, 48 GB, sm_86 +- L40S, 48 GB, sm_89 +- H100, 80 GB, sm_90 +- H200, 141 GB, sm_90 +- B200, 180 GB, sm_100 +- RTX PRO 4500 Blackwell, 16 GB MIG slices, sm_120 +- RTX PRO 6000 Blackwell, 96 GB, sm_120 On other clusters the same rule applies by compute capability: sm_80 (Ampere) through sm_120 (Blackwell) all work with a 2.5.0 or newer image. @@ -375,7 +377,7 @@ While you are still on an older image, keep inference off those nodes with `slur
-MIG slices (gpu60-68) +MIG slices Those nodes are RTX PRO 4500 cards split into 16 GB `1g.16gb` MIG instances. They need no special `slurm_gres`: a plain `gpu:1` request lands on one slice and SLURM sets @@ -450,15 +452,15 @@ you hit these. uses the biggest tier and spills to host RAM via unified memory. ```yaml - # Example for the EMBL GPU pool; replace nodes with your cluster's (nothing is hard-coded): + # Example GPU tiers; replace these node names with your cluster's: structure_inference_gpu_vram_headroom: 1.0 # <1.0 tolerates that fraction of host spill structure_inference_gpu_tiers: - - {min_vram_gb: 16, nodes: "gpu60,gpu61,gpu62,gpu63,gpu64,gpu65,gpu66,gpu67,gpu68"} # RTX PRO 4500, 16GB MIG - - {min_vram_gb: 24, nodes: "gpu21,gpu22,gpu29,gpu30,gpu31,gpu32,gpu33,gpu34,gpu35,gpu36,gpu37"} - - {min_vram_gb: 40, nodes: "gpu25,gpu26,gpu27,gpu28"} - - {min_vram_gb: 48, nodes: "gpu40,gpu41,gpu42,gpu43,gpu44,gpu45,gpu46,gpu47,gpu48"} - - {min_vram_gb: 80, nodes: "gpu38,gpu39"} - - {min_vram_gb: 96, nodes: "gpu51,gpu52,gpu53"} # RTX PRO 6000 Blackwell + - {min_vram_gb: 16, nodes: "gpu-16gb-01,gpu-16gb-02"} # RTX PRO 4500, 16GB MIG + - {min_vram_gb: 24, nodes: "gpu-24gb-01,gpu-24gb-02"} + - {min_vram_gb: 40, nodes: "gpu-40gb-01,gpu-40gb-02"} + - {min_vram_gb: 48, nodes: "gpu-48gb-01,gpu-48gb-02"} + - {min_vram_gb: 80, nodes: "gpu-80gb-01,gpu-80gb-02"} + - {min_vram_gb: 96, nodes: "gpu-96gb-01,gpu-96gb-02"} # RTX PRO 6000 Blackwell ``` When set this drives `--exclude` per job and **overrides** `structure_inference_gpu_model` (the two @@ -468,7 +470,7 @@ you hit these. partition(s); it excludes nodes by name, so if you span **multiple partitions** (see above) make sure the tier node lists cover every partition you submit to. - **Exclude specific nodes** with `slurm_exclude_nodes`, passed verbatim to `sbatch --exclude` - (e.g. `"gpu51,gpu52"`). `--exclude` is allowed in `slurm_extra` whereas + (e.g. `"gpu-96gb-01,gpu-96gb-02"`). `--exclude` is allowed in `slurm_extra` whereas `--constraint`/`--gres`/`--gpus` are not, so it is the supported way to drop a few nodes while keeping the rest of the partition. The usual reason to need it is a GPU the container image is too old for; see [GPU compatibility](#gpu-compatibility). @@ -512,8 +514,7 @@ read with `nvidia-smi` once the job lands on a node, and the host RAM is the job ceiling within the SLURM allocation so XLA cannot oversubscribe host RAM beyond what the job requested — which would otherwise get the job OOM-killed. The chosen fraction is logged as a `[unified-memory]` line at the top of the job log. Pin a number instead if -you want a fixed multiplier regardless of GPU/RAM (mirrors the EMBL `run_AF_multimer.sh` -convention). +you want a fixed multiplier regardless of GPU/RAM. > The fraction is computed in the job shell rather than via the SLURM executor: the > executor passes the submit environment through with `--export=ALL` but offers no @@ -542,7 +543,8 @@ structure_inference mem = safety * (structure_inference_ram_bytes + per_token_s ``` - `seq_len` is the query length; `N` is the **total residues of the complex** (the - AlphaFold token count, summed over chains and copy numbers). AlphaFold's pair + AlphaFold token count, summed over chains and copy numbers). For AlphaFold 3, `N` is + rounded up to the `--buckets` size the model pads to. AlphaFold's pair representation is `O(N^2)`, hence the quadratic inference term. - **The coefficients default by backend** (selected from `--data_pipeline` / `--fold_backend`). AlphaFold-Multimer (AF2) is heavier than AlphaFold 3 — measured AF2 inference host RSS was @@ -677,38 +679,117 @@ batch_max_tokens: 0 # optional cap on summed residues per batch (0 = no cap)
-### Batched local MMseqs2-GPU features (AlphaFold 3) +### Using precomputed features + +If you have precomputed protein features, specify the directory: + +```yaml +feature_directory: + - "/path/to/directory/with/features/" +``` + +> **Note**: If your features are compressed, set `compress-features: True` in the config. + +### Feature generation flags (`create_individual_features.py`) + +Tweak the feature-generation step by editing `create_feature_arguments` (or by running the script +manually). + +
+Commonly used flags + +- `--data_pipeline {alphafold2,alphafold3}` – choose the feature format to emit. +- `--db_preset {full_dbs,reduced_dbs}` – switch between the full BFD stack or the reduced databases. +- `--use_mmseqs2` – rely on the remote MMseqs2 API; skips local jackhmmer/HHsearch database lookups. + To reuse a3m files generated locally with `colabfold_search`, also set `--use_precomputed_msas=True` + (see the [mmseqs2 manual](https://github.com/KosinskiLab/AlphaPulldown/blob/main/manuals/mmseqs2_manual.md)); + otherwise the remote API is contacted again and your a3m files are overwritten. +- `--skip_msa` – generate query-only single-sequence features instead of running bulk MSA searches. + Use those feature pickles with `run_structure_prediction.py --pair_msa=False`. +- `--use_precomputed_msas` / `--save_msa_files` – reuse stored MSAs (`/.a3m`) or + keep new ones for later runs. Required to reuse precomputed MMseqs2/ColabFold a3m files rather + than regenerating them. +- `--compress_features` – compress the generated features to save space: `*.pkl.xz` for the AlphaFold2 pipeline, `*_af3_input.json.xz` for AlphaFold3. Both are read back transparently, so compressed feature sets can be used directly (this is how the [features database](https://alphapulldown.s3.embl.de) ships them). +- `--skip_existing` – leave existing feature files untouched (safe for reruns). +- `--keep_msas` – refresh **templates only** in features that already exist in `--output_dir`, keeping their MSAs. Use it when the template database or `--max_template_date` has moved but the alignments are still valid: it costs a template search (minutes) instead of a full MSA run (hours). Works for both pipelines — AlphaFold2 features get their `template_*` block replaced, AlphaFold3 features are re-processed through AF3's "search for templates only" path. Proteins with no stored features are generated normally, and it takes precedence over `--skip_existing`. Cannot be combined with `--use_mmseqs2` (which fetches MSAs and templates together) or `--skip_msa` (no MSAs to keep). +- `--seq_index N` – only process the N‑th sequence from the FASTA list. +- `--use_hhsearch`, `--re_search_templates_mmseqs2` – toggle template search implementations. +- `--path_to_mmt`, `--description_file`, `--multiple_mmts` – enable TrueMultimer CSV-driven feature sets. +- `--max_template_date YYYY-MM-DD` – required cutoff for template structures; keeps runs reproducible. + +
+ +### Batched local MMseqs2 features (AlphaFold 2 and 3)
-Faster AlphaFold 3 MSAs using local MMseqs2 instead of jackhmmer/HHblits +Faster MSAs using local MMseqs2 instead of jackhmmer/HHblits -Off by default. Proteins are split into bounded GPU shards searched with MMseqs2, and a -separate CPU stage runs AlphaFold 3's own template search and writes one standard AF3 -JSON per chain — so template work can use CPU and big-memory partitions in parallel. -AlphaFold 2 feature generation and the remote `--use_mmseqs2` path are unchanged. RNA -chains are supported once the RNA databases are configured. +Off by default. Missing proteins are split into bounded shards searched with MMseqs2 — +as GPU jobs, or CPU jobs with `use_gpu: false` — and a separate CPU stage turns each +chain's alignment into standard features, so template work can use CPU and big-memory +partitions in parallel. Which features follows `--data_pipeline` in +`create_feature_arguments`: an AF3 JSON per chain, or an AF2 pickle. The remote +`--use_mmseqs2` path is unchanged. RNA chains are supported for AlphaFold 3 once the RNA +databases are configured. ```yaml mmseqs2_features: enabled: true + use_gpu: true temp_dir: /local-fast-scratch/mmseqs + template_database_ids: + pdb_seqres: pdb-seqres-2026-08 + mmcif: pdb-mmcif-2026-08 + # pdb70: pdb70-2026-08 # required for AF2 --use_hhsearch databases: - uniref90: {path: /db/mmseqs/uniref90, identifier: uniref90-2026-08, max_sequences: 10000} - mgnify: {path: /db/mmseqs/mgnify, identifier: mgnify-2026-08, max_sequences: 5000} - small_bfd: {path: /db/mmseqs/small_bfd, identifier: small-bfd-2026-08, max_sequences: 5000} - uniprot: {path: /db/mmseqs/uniprot, identifier: uniprot-2026-08, max_sequences: 50000} + uniref90: {path: /db/mmseqs/uniref90_gpu, identifier: uniref90-2026-08, max_sequences: 10000} + mgnify: {path: /db/mmseqs/mgnify_gpu, identifier: mgnify-2026-08, max_sequences: 5000} + small_bfd: {path: /db/mmseqs/small_bfd_gpu, identifier: small-bfd-2026-08, max_sequences: 5000} + uniprot: {path: /db/mmseqs/uniprot_gpu, identifier: uniprot-2026-08, max_sequences: 50000} ``` The protein databases must be padded (`makepaddedseqdb`); the RNA ones must not be. `scripts/setup_databases.sh --mmseqs` builds them. The native AlphaFold 3 database tree -is still required — these are additive, not a replacement. +is still required — these are additive, not a replacement. Memory and walltime for both +stages are derived from the configured databases; the remaining knobs live in the +ADVANCED section of `config/config.yaml`. + +**The GPU search reads every padded database in full**, about 375 GB for the four +protein ones. On network storage a cold first attempt is bound by that read, not by the +GPU: measured ~150 MB/s from NFS with the GPU idle, about an hour per shard, against +minutes once the node's page cache holds the databases. If first attempts time out, +raise `search_runtime_base_minutes` or stage the databases on local disk; the retry, +with twice the walltime, recovers either way. **Depth is not identical to the native pipeline.** Measured on eight *B. subtilis* proteins it was ~90% of jackhmmer's unpaired depth overall, but only 54–68% on the shallowest families. Whether that costs accuracy is untested, so treat it as opt-in and spot-check your own targets. -Databases, RNA, tuning, caching and caveats: [docs/mmseqs2_rna.md](docs/mmseqs2_rna.md). +**For AlphaFold 2** set `--data_pipeline: alphafold2` and enable the block above. The +MSA recipe is AlphaFold 2's `reduced_dbs` set (no BFD/UniRef30 HHblits arm); templates +come from the AlphaFold 2 database tree, and `--use_hhsearch` and any explicit template +paths in `create_feature_arguments` reach the finalization stage. The MSA cache +remains reusable when only the template database changes. With +`--use_hhsearch: true`, set `mmseqs2_features.template_database_ids.pdb70` to the +immutable PDB70 build identity; `pdb_seqres` is then unused. Other template searches +require `pdb_seqres`, and every search requires `mmcif`. Update the relevant ID when +rebuilding a database, even at the same path; this invalidates finalized features. +The native MSA arguments do not reach finalization because this stage replaces +that search. Use a matching prediction image, such as +`docker://kosinskilab/alphafold2:2.9.0`, for AlphaFold 2. AlphaFold 2 finalization is +heavier than AlphaFold 3's because template featurization dominates it — median ~1 GB and 2 min, but up to +19 GB and 90 min, set by which structures the templates come from rather than by length +— so its defaults request 16 GB (times the safety factor) and 60 min. Against native +`reduced_dbs` features on 12 heterodimers released after AF2-multimer's training cutoff, +top-ranked DockQ averaged 0.56 against 0.59, with 9 of 12 interfaces acceptable either +way. + +Alignments preserve insertions for both backends. Older MSA bundles that lost +insertions are regenerated automatically. + +Databases, RNA, AlphaFold 2, tuning, caching and caveats: +[AlphaPulldown docs/mmseqs2_rna.md](https://github.com/KosinskiLab/AlphaPulldown/blob/main/docs/mmseqs2_rna.md).
@@ -822,51 +903,9 @@ structure_inference_arguments: --- -### Using precomputed features - -If you have precomputed protein features, specify the directory: - -```yaml -feature_directory: - - "/path/to/directory/with/features/" -``` - -> **Note**: If your features are compressed, set `compress-features: True` in the config. - -### Feature generation flags (`create_individual_features.py`) - -Tweak the feature-generation step by editing `create_feature_arguments` (or by running the script -manually). - -
-Commonly used flags - -- `--data_pipeline {alphafold2,alphafold3}` – choose the feature format to emit. -- `--db_preset {full_dbs,reduced_dbs}` – switch between the full BFD stack or the reduced databases. -- `--use_mmseqs2` – rely on the remote MMseqs2 API; skips local jackhmmer/HHsearch database lookups. - To reuse a3m files generated locally with `colabfold_search`, also set `--use_precomputed_msas=True` - (see the [mmseqs2 manual](https://github.com/KosinskiLab/AlphaPulldown/blob/main/manuals/mmseqs2_manual.md)); - otherwise the remote API is contacted again and your a3m files are overwritten. -- `--skip_msa` – generate query-only single-sequence features instead of running bulk MSA searches. - Use those feature pickles with `run_structure_prediction.py --pair_msa=False`. -- `--use_precomputed_msas` / `--save_msa_files` – reuse stored MSAs (`/.a3m`) or - keep new ones for later runs. Required to reuse precomputed MMseqs2/ColabFold a3m files rather - than regenerating them. -- `--compress_features` – compress the generated features to save space: `*.pkl.xz` for the AlphaFold2 pipeline, `*_af3_input.json.xz` for AlphaFold3. Both are read back transparently, so compressed feature sets can be used directly (this is how the [features database](https://alphapulldown.s3.embl.de) ships them). -- `--skip_existing` – leave existing feature files untouched (safe for reruns). -- `--keep_msas` – refresh **templates only** in features that already exist in `--output_dir`, keeping their MSAs. Use it when the template database or `--max_template_date` has moved but the alignments are still valid: it costs a template search (minutes) instead of a full MSA run (hours). Works for both pipelines — AlphaFold2 features get their `template_*` block replaced, AlphaFold3 features are re-processed through AF3's "search for templates only" path. Proteins with no stored features are generated normally, and it takes precedence over `--skip_existing`. Cannot be combined with `--use_mmseqs2` (which fetches MSAs and templates together) or `--skip_msa` (no MSAs to keep). -- `--seq_index N` – only process the N‑th sequence from the FASTA list. -- `--use_hhsearch`, `--re_search_templates_mmseqs2` – toggle template search implementations. -- `--path_to_mmt`, `--description_file`, `--multiple_mmts` – enable TrueMultimer CSV-driven feature sets. -- `--max_template_date YYYY-MM-DD` – required cutoff for template structures; keeps runs reproducible. - -
- ---- - -## How to Cite +## How to cite -If AlphaPulldown contributed significantly to your research, please cite [the corresponding publication](https://doi.org/10.1093/bioinformatics/btaf115) in *Bioinformatics*: +If AlphaPulldown (or this workflow) contributed to your research, please cite [Molodenskiy et al., 2025](https://doi.org/10.1093/bioinformatics/btaf115): ```bibtex @article{Molodenskiy2025AlphaPulldown2, diff --git a/alphapulldown/__init__.py b/alphapulldown/__init__.py index 892994aa..43ce13db 100755 --- a/alphapulldown/__init__.py +++ b/alphapulldown/__init__.py @@ -1 +1 @@ -__version__ = "2.8.0" +__version__ = "2.9.0" diff --git a/alphapulldown/af2_feature_finalizer.py b/alphapulldown/af2_feature_finalizer.py new file mode 100644 index 00000000..2319a2df --- /dev/null +++ b/alphapulldown/af2_feature_finalizer.py @@ -0,0 +1,461 @@ +"""AlphaFold 2 features from a local MMseqs2 MSA bundle. + +The search stage (``feature_batch.MsaBatch``) is backend-neutral: it writes one MSA +bundle per chain. This module turns a bundle into what the AlphaFold 2 backend +reads -- a pickled ``alphapulldown.objects.MonomericObject`` -- building it the way +``alphafold.data.pipeline.DataPipeline.process`` builds features from jackhmmer, +so the result drops into existing AlphaFold 2 inference unchanged. + +What is reproduced from native AlphaFold 2: + +- per-database caps, counting the query row as AlphaFold 2 does: uniref90 at + 10 000 and mgnify at 501, small BFD uncapped (``pipeline.py``: jackhmmer's + ``max_sto_sequences``, which stops at that many sequence names, query first) +- merge order uniref90, BFD, MGnify (``pipeline.py:265``). Row order matters: + AlphaFold 2 deduplicates in that order and samples its MSA from the top +- templates searched from uniref90 ALONE, never from the merged alignment +- the paired UniProt alignment truncated to 50 000 rows, as + ``MonomericObject.all_seq_msa_features`` does, and exposed as ``*_all_seq`` + +Where it cannot be exact, and why that is acceptable: + +- The database recipe is uniref90, MGnify, small BFD and UniProt -- AlphaFold 2's + ``reduced_dbs`` set. There is no BFD/UniRef30 HHblits arm, so these features are + comparable to ``--db_preset=reduced_dbs``, not ``full_dbs``. +- The bundle deduplicated rows across databases before this module sees them, so + the caps apply to each database's rows after that deduplication. Native + AlphaFold 2 caps raw hits first. The mgnify cap can therefore admit a few more + unique rows than native, and a sequence both MGnify and small BFD found counts + against MGnify's cap. Both effects touch only rows duplicated across databases. +- The template profile is built from the uniref90 A3M with insertions removed. + jackhmmer's Stockholm carries insert columns; A3M insertions are per row and not + aligned to each other, so they cannot be turned back into columns faithfully. + Match columns -- which decide the profile's states -- are identical. + +And one deliberate improvement: UniProt accession identifiers are filled from the +alignment headers, where native features leave them empty. Nothing here ever +queries UniProt over the network; see :func:`_no_network`. +""" + +from __future__ import annotations + +import copy +import dataclasses +from datetime import date +import json +import lzma +import os +from pathlib import Path +import pickle +import tempfile +from typing import Any, Mapping, Sequence + +from alphapulldown.feature_batch import ( + PROTEIN, + UNPAIRED_DATABASE_NAMES, + FeatureArtifact, + FeatureBatchResult, + FeatureFailure, + FeatureRequest, + SearchedMsas, + _fasta_records, + _validate_feature_requests, + read_msa_bundle, + searched_msas_from_payload, +) + + +# AlphaFold 2's own caps, counting the query row the way it does. +AF2_MAX_SEQUENCES = {"uniref90": 10_000, "mgnify": 501} +# pipeline.py:265 -- make_msa_features((uniref90_msa, bfd_msa, mgnify_msa)). +AF2_MERGE_ORDER = ("uniref90", "small_bfd", "mgnify") +# MonomericObject.all_seq_msa_features truncates the UniProt alignment here. +PAIRED_MAX_SEQUENCES = 50_000 +TEMPLATE_SEARCHERS = ("hmmsearch", "hhsearch") +# Bump when the construction below changes, so features an older construction +# built are regenerated rather than reused. +_AF2_FEATURE_SCHEMA = 1 + + +@dataclasses.dataclass(frozen=True, slots=True) +class Af2MsaInputs: + """The three alignments AlphaFold 2 features are built from.""" + + # Becomes msa / deletion_matrix_int: all three databases, capped, in AF2 order. + main_a3m: str + # uniref90 alone: what the template profile is built from. + template_a3m: str + # UniProt: becomes *_all_seq, which pairs chains by species. + paired_a3m: str + + +def _a3m(records: Sequence[tuple[str, str]]) -> str: + return "".join(f">{description}\n{sequence}\n" for description, sequence in records) + + +def af2_msa_inputs(msas: SearchedMsas) -> Af2MsaInputs: + """Cut a bundle's alignments into the shapes native AlphaFold 2 would have.""" + query, by_database = msas.rows_by_database() + missing = [name for name in UNPAIRED_DATABASE_NAMES if name not in by_database] + if missing: + raise ValueError( + "MSA bundle does not say which rows came from " + + ", ".join(missing) + + "; AlphaFold 2 needs each database's rows separately" + ) + + def capped(name: str) -> list[tuple[str, str]]: + rows = by_database[name] + cap = AF2_MAX_SEQUENCES.get(name) + # AlphaFold 2 counts the query toward its cap, so a cap of N keeps N - 1 hits. + return rows if cap is None else rows[: cap - 1] + + blocks = {name: capped(name) for name in AF2_MERGE_ORDER} + paired_records = _fasta_records(msas.paired) + if not paired_records: + raise ValueError( + "MSA bundle has no paired UniProt alignment; AlphaFold 2 multimer " + "pairing needs one" + ) + return Af2MsaInputs( + main_a3m=_a3m( + [query, *(row for name in AF2_MERGE_ORDER for row in blocks[name])] + ), + template_a3m=_a3m([query, *blocks["uniref90"]]), + paired_a3m=_a3m(paired_records[:PAIRED_MAX_SEQUENCES]), + ) + + +def _no_network(accessions: Sequence[str]) -> dict[str, str]: + """Resolve nothing, rather than ask UniProt. + + The shared identifier helper falls back to UniProt REST lookups for + accessions whose header carries no species. A local batch of thousands of + chains must not start doing that unannounced -- and it has no need to: the + UniProt database's canonical ``sp|ACC|NAME_SPECIES`` headers carry the species + already, and AlphaFold 2 reads it from them directly. Anything unparseable + stays unresolved, exactly as it would in native features. + """ + del accessions + return {} + + +def _offline_accessions(a3m: str, *, rows: int): + """Accession per alignment row, deduplicated exactly as make_msa_features is.""" + from alphapulldown.utils.mmseqs_species_identifiers import ( + build_mmseq_identifier_features, + ) + + identifiers = build_mmseq_identifier_features( + a3m, species_resolver=_no_network, expected_rows=rows + ) + accessions = identifiers["msa_uniprot_accession_identifiers"] + if len(accessions) != rows: + raise ValueError( + f"accession identifiers cover {len(accessions)} rows but the MSA has " + f"{rows}; they would index the wrong sequences" + ) + return accessions + + +@dataclasses.dataclass(frozen=True, slots=True) +class Af2TemplateStackSettings: + """Everything the AlphaFold 2 template searcher and featurizer are built from. + + Explicit values rather than global flags, so a caller states what it uses + instead of depending on some earlier call having rewritten FLAGS. + """ + + template_mmcif_dir: str + max_template_date: str + kalign_binary_path: str + obsolete_pdbs_path: str | None = None + use_hhsearch: bool = False + # hmmsearch against PDB seqres, the default. + hmmsearch_binary_path: str | None = None + hmmbuild_binary_path: str | None = None + pdb_seqres_database_path: str | None = None + # hhsearch against PDB70, under --use_hhsearch. + hhsearch_binary_path: str | None = None + pdb70_database_path: str | None = None + + @property + def searcher_name(self) -> str: + return "hhsearch" if self.use_hhsearch else "hmmsearch" + + +def build_af2_template_stack(settings: Af2TemplateStackSettings): + """The AlphaFold 2 template searcher and featurizer, as native features use.""" + from alphafold.data import templates + from alphafold.data.tools import hhsearch, hmmsearch + + if settings.use_hhsearch: + searcher = hhsearch.HHSearch( + binary_path=settings.hhsearch_binary_path, + databases=[settings.pdb70_database_path], + ) + featurizer = templates.HhsearchHitFeaturizer( + mmcif_dir=settings.template_mmcif_dir, + max_template_date=settings.max_template_date, + max_hits=20, + kalign_binary_path=settings.kalign_binary_path, + release_dates_path=None, + obsolete_pdbs_path=settings.obsolete_pdbs_path, + ) + return searcher, featurizer + featurizer = templates.HmmsearchHitFeaturizer( + mmcif_dir=settings.template_mmcif_dir, + max_template_date=settings.max_template_date, + max_hits=20, + kalign_binary_path=settings.kalign_binary_path, + obsolete_pdbs_path=settings.obsolete_pdbs_path, + release_dates_path=None, + ) + searcher = hmmsearch.Hmmsearch( + binary_path=settings.hmmsearch_binary_path, + hmmbuild_binary_path=settings.hmmbuild_binary_path, + database_path=settings.pdb_seqres_database_path, + ) + return searcher, featurizer + + +@dataclasses.dataclass(frozen=True, slots=True) +class Af2FeatureFinalizationSettings: + """CPU AlphaFold 2 finalization settings and complete template provenance.""" + + output_dir: Path + msa_input_dir: Path + max_template_date: str + template_seqres_database_id: str | None + template_mmcif_database_id: str + # hmmsearch against PDB seqres, or hhsearch against PDB70 (--use_hhsearch). + # The two find different templates, so which one ran is part of the identity. + template_searcher: str = "hmmsearch" + template_pdb70_database_id: str | None = None + compress: bool = False + base_metadata: Mapping[str, Any] = dataclasses.field(default_factory=dict) + + +class Af2FeatureFinalizer: + """Turn persisted MSA bundles into AlphaFold 2 feature pickles on CPU.""" + + def __init__( + self, + *, + settings: Af2FeatureFinalizationSettings, + template_searcher: Any, + template_featurizer: Any, + ): + if not isinstance(settings, Af2FeatureFinalizationSettings): + raise TypeError( + "Af2FeatureFinalizer settings must be Af2FeatureFinalizationSettings" + ) + self._settings = settings + self._template_searcher = template_searcher + self._template_featurizer = template_featurizer + + def generate(self, requests: Sequence[FeatureRequest]) -> FeatureBatchResult: + requests = tuple(requests) + self._validate(requests) + self._settings.output_dir.mkdir(parents=True, exist_ok=True) + written = [] + reused = [] + failures = [] + for request in requests: + try: + if request.molecule_type != PROTEIN: + raise ValueError( + f"{request.name!r} is {request.molecule_type}: AlphaFold 2 " + "has no MSA features for anything but protein chains" + ) + payload = read_msa_bundle( + self._settings.msa_input_dir, request, require_row_spans=True + ) + msas = searched_msas_from_payload(payload) + provenance = self._provenance(payload) + cached = self._read_matching_artifact(request, provenance) + if cached is not None: + reused.append(FeatureArtifact(name=request.name, path=cached)) + continue + feature_dict = self._feature_dict(request, af2_msa_inputs(msas)) + path = self._publish(request, feature_dict, provenance) + written.append(FeatureArtifact(name=request.name, path=path)) + except Exception as exc: + failures.append(FeatureFailure(name=request.name, error=str(exc))) + return FeatureBatchResult( + written=tuple(written), reused=tuple(reused), failures=tuple(failures) + ) + + def _validate(self, requests: Sequence[FeatureRequest]) -> None: + _validate_feature_requests(requests) + if self._settings.template_searcher not in TEMPLATE_SEARCHERS: + raise ValueError( + "template_searcher must be one of " + f"{', '.join(TEMPLATE_SEARCHERS)}, not " + f"{self._settings.template_searcher!r}" + ) + for field_name in ( + "max_template_date", + "template_mmcif_database_id", + "template_pdb70_database_id" if self._settings.template_searcher == "hhsearch" + else "template_seqres_database_id", + ): + value = getattr(self._settings, field_name) + if value is None or not str(value).strip(): + raise ValueError(f"{field_name} requires a non-empty value") + + def _feature_dict( + self, request: FeatureRequest, inputs: Af2MsaInputs + ) -> dict[str, Any]: + from alphafold.data import msa_pairing, parsers, pipeline + + from alphapulldown.objects import add_template_feature_defaults + from alphapulldown.utils.template_reuse import ( + search_templates, + stockholm_from_a3m, + ) + + sequence = request.sequence + features = dict( + pipeline.make_sequence_features( + sequence=sequence, description=request.name, num_res=len(sequence) + ) + ) + + main = pipeline.make_msa_features([parsers.parse_a3m(inputs.main_a3m)]) + main["msa_uniprot_accession_identifiers"] = _offline_accessions( + inputs.main_a3m, rows=main["msa"].shape[0] + ) + features.update(main) + + features.update( + search_templates( + self._template_searcher, + self._template_featurizer, + query_sequence=sequence, + stockholm_msa=stockholm_from_a3m(inputs.template_a3m), + ) + ) + + # The paired alignment is searched separately against UniProt, whose + # headers carry the species AlphaFold 2 pairs chains by. It is not a copy + # of the unpaired features, which is what the remote path makes do with. + paired = pipeline.make_msa_features([parsers.parse_a3m(inputs.paired_a3m)]) + paired["msa_uniprot_accession_identifiers"] = _offline_accessions( + inputs.paired_a3m, rows=paired["msa"].shape[0] + ) + pairable = msa_pairing.MSA_FEATURES + ( + "msa_species_identifiers", + "msa_uniprot_accession_identifiers", + ) + features.update( + {f"{key}_all_seq": value for key, value in paired.items() if key in pairable} + ) + + add_template_feature_defaults(features, sequence) + return features + + def _provenance(self, msa_payload: Mapping[str, Any]) -> dict[str, Any]: + """Everything that decides the pickle's content, for cache reuse.""" + return { + "af2_feature_schema": _AF2_FEATURE_SCHEMA, + "mmseqs2": msa_payload["provenance"], + "af2_templates": self._template_signature(), + } + + def _template_signature(self) -> dict[str, Any]: + # Software versions, not base_metadata's wall-clock date, which would miss + # on every run -- the same choice the AlphaFold 3 finalizer makes. + database = ( + {"pdb70_database_id": self._settings.template_pdb70_database_id} + if self._settings.template_searcher == "hhsearch" + else {"pdb_seqres_database_id": self._settings.template_seqres_database_id} + ) + return { + "max_template_date": self._settings.max_template_date, + **database, + "mmcif_database_id": self._settings.template_mmcif_database_id, + "template_searcher": self._settings.template_searcher, + "software": dict(self._settings.base_metadata.get("software", {})), + } + + def _read_matching_artifact( + self, request: FeatureRequest, provenance: Mapping[str, Any] + ) -> Path | None: + from alphapulldown.utils.lightweight_pickles import load_lightweight_pickle + + path = self._artifact_path(request.name) + if not path.exists(): + return None + try: + monomer = load_lightweight_pickle(path) + except Exception: + return None + if getattr(monomer, "sequence", None) != request.sequence: + return None + if getattr(monomer, "local_msa_provenance", None) != provenance: + return None + return path + + def _publish( + self, + request: FeatureRequest, + feature_dict: dict[str, Any], + provenance: Mapping[str, Any], + ) -> Path: + from alphapulldown.objects import MonomericObject + + monomer = MonomericObject(request.name, request.sequence) + monomer.feature_dict = feature_dict + monomer.skip_msa = False + # Carried on the object so a later run can tell, from the pickle alone, + # whether it was built from the same search and template settings. + monomer.local_msa_provenance = dict(provenance) + + metadata = copy.deepcopy(dict(self._settings.base_metadata)) + other = metadata.setdefault("other", {}) + # The same keys the AlphaFold 3 finalizer writes, so one reader serves both. + # The search mode, cpu or gpu, is inside the provenance. + other["msa_backend"] = "mmseqs2-gpu" + other["mmseqs2_gpu"] = provenance["mmseqs2"] + other["af2_templates"] = provenance["af2_templates"] + metadata_suffix = ".json.xz" if self._settings.compress else ".json" + _write_atomic( + self._settings.output_dir + / f"{request.name}_feature_metadata_{date.today()}{metadata_suffix}", + json.dumps(metadata).encode("utf-8"), + ) + # The pickle is the output a workflow waits for, so it is published last: + # its existence implies its metadata exists too. + path = self._artifact_path(request.name) + _write_atomic(path, pickle.dumps(monomer)) + return path + + def _artifact_path(self, name: str) -> Path: + suffix = ".pkl.xz" if self._settings.compress else ".pkl" + return self._settings.output_dir / f"{name}{suffix}" + + +def _write_atomic(path: Path, content: bytes) -> None: + """Publish a file whole or not at all, compressed when its name says .xz.""" + descriptor, temporary_name = tempfile.mkstemp( + prefix=f".{path.name}.", suffix=".tmp", dir=path.parent + ) + temporary_path = Path(temporary_name) + try: + with os.fdopen(descriptor, "wb") as raw_handle: + if path.suffix == ".xz": + with lzma.open(raw_handle, "wb") as handle: + handle.write(content) + else: + raw_handle.write(content) + raw_handle.flush() + os.fsync(raw_handle.fileno()) + os.replace(temporary_path, path) + directory_fd = os.open(path.parent, os.O_RDONLY) + try: + os.fsync(directory_fd) + finally: + os.close(directory_fd) + finally: + temporary_path.unlink(missing_ok=True) diff --git a/alphapulldown/feature_batch.py b/alphapulldown/feature_batch.py index 32fbdb2e..495c75a6 100644 --- a/alphapulldown/feature_batch.py +++ b/alphapulldown/feature_batch.py @@ -19,6 +19,11 @@ embed_metadata_in_af3_json, extract_metadata_from_af3_json, ) +from alphapulldown.utils.msa_formats import ( + StitchMismatch, + stitch_headers_and_insertions, + strip_insertions, +) PROTEIN = "protein" @@ -64,6 +69,12 @@ # future GPU-capable nucleotide search does not silently reuse these bundles. NUCLEOTIDE_SEARCH_MODE = "cpu" +# How the alignment text was produced, recorded in every bundle's provenance. +# Bundles written before insertions were recovered came from mode 2 alone and carry +# none -- 81.7% of small_bfd hits and 86.4% of uniprot hits lost theirs, measured on +# a real 586-residue query -- so they must never satisfy a request made now. +_MSA_FORMAT = {"headers": "result2msa mode 2", "sequences": "result2msa mode 5"} + def _describe_exit(returncode) -> str: """Say what an MMseqs2 exit code means, especially when it died on a signal. @@ -283,6 +294,39 @@ class MsaFailure: error: str +@dataclasses.dataclass(frozen=True, slots=True) +class SearchedMsas: + """What one search produced for one sequence, before it becomes a bundle.""" + + unpaired: str + paired: str + # How many rows of ``unpaired`` each database contributed, in merge order and + # after deduplication. The query row belongs to none of them. AlphaFold 2 builds + # its template profile from uniref90 ALONE and caps each database separately, so + # the merged alignment is unusable to it unless these boundaries are kept. + unpaired_rows: tuple[tuple[str, int], ...] = () + + def rows_by_database( + self, + ) -> tuple[tuple[str, str], dict[str, list[tuple[str, str]]]]: + """The query record, and each database's own rows, recovered from the spans.""" + records = _fasta_records(self.unpaired) + if not records: + raise ValueError("MSA bundle has an empty unpaired alignment") + query, hits = records[0], records[1:] + by_database: dict[str, list[tuple[str, str]]] = {} + start = 0 + for name, count in self.unpaired_rows: + by_database[name] = hits[start : start + count] + start += count + if start != len(hits): + raise ValueError( + f"MSA bundle row spans cover {start} rows but the alignment has " + f"{len(hits)} besides the query" + ) + return query, by_database + + @dataclasses.dataclass(frozen=True, slots=True) class MsaBatchResult: written: tuple[MsaArtifact, ...] @@ -371,7 +415,19 @@ def result_to_msa( database: DatabaseSpec, result_db: Path, msa_db: Path, - ) -> None: ... + ) -> None: + """Format the hits with their full database headers and no insertions.""" + ... + + def result_to_a3m( + self, + query_db: Path, + database: DatabaseSpec, + result_db: Path, + msa_db: Path, + ) -> None: + """Format the same hits as A3M: insertions kept, headers cut to one token.""" + ... def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: ... @@ -379,9 +435,26 @@ def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: .. class SubprocessMmseqsProcess: """Production adapter for one local MMseqs2 executable.""" - def __init__(self, binary_path: str | Path, *, gpu: bool = True): + def __init__( + self, + binary_path: str | Path, + *, + gpu: bool = True, + db_load_mode: int | None = None, + ): self._binary_path = str(binary_path) self._gpu = gpu + # How MMseqs2 reads the target database (0 auto, 1 fread, 2 mmap, + # 3 mmap+touch). Deliberately a process-level setting rather than part of + # MsaBatchSettings: it changes memory behaviour and nothing else, so it + # must never reach the cache signature. Two runs that differ only here + # produce the same alignment and must keep reusing each other's bundles. + self._db_load_mode = db_load_mode + + def _db_load_mode_option(self) -> tuple[str, ...]: + if self._db_load_mode is None: + return () + return ("--db-load-mode", str(self._db_load_mode)) def _run(self, command: Sequence[str]) -> str: try: @@ -449,8 +522,14 @@ def search( "1" if gpu else "0", ) + ( + # Iterative profile search is protein-only: measured on the pinned + # build, --num-iterations 3 on a nucleotide search exits 1 ("Alignment + # died", or "no diagonal information" on a one-sequence database). + # RNA provenance correctly never records it. ("--num-iterations", str(settings.num_iterations)) - if settings.num_iterations and settings.num_iterations > 1 + if settings.num_iterations + and settings.num_iterations > 1 + and not nucleotide else () ) + (("--search-type", "3") if nucleotide else ()) @@ -459,6 +538,7 @@ def search( if settings.split_memory_limit else () ) + + self._db_load_mode_option() ) def result_to_msa( @@ -478,6 +558,31 @@ def result_to_msa( "--msa-format-mode", "2", ) + + self._db_load_mode_option() + ) + + def result_to_a3m( + self, + query_db: Path, + database: DatabaseSpec, + result_db: Path, + msa_db: Path, + ) -> None: + # Mode 5 is the only format that keeps insertions, and it keeps nothing of + # the header but the database key -- so it is run alongside mode 2, not + # instead of it. Measured at 2 s against a 947 s search on small_bfd and + # 13 s against 3739 s on uniprot, roughly 16 ms per hit. + self._run( + ( + "result2msa", + str(query_db), + str(database.path), + str(result_db), + str(msa_db), + "--msa-format-mode", + "5", + ) + + self._db_load_mode_option() ) def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: @@ -531,7 +636,7 @@ def generate(self, requests: Sequence[FeatureRequest]) -> MsaBatchResult: missing_requests = [] # Keyed by molecule type as well as sequence: the same letters searched as a # protein and as RNA are two different searches with two different answers. - msa_by_sequence: dict[tuple[str, str], tuple[str, str]] = {} + msa_by_sequence: dict[tuple[str, str], SearchedMsas] = {} for request in requests: cached = self._read_matching_msa(request) if cached is None: @@ -540,8 +645,7 @@ def generate(self, requests: Sequence[FeatureRequest]) -> MsaBatchResult: path, payload = cached reused.append(MsaArtifact(name=request.name, path=path)) msa_by_sequence.setdefault( - _request_key(request), - (payload["unpairedMsa"], payload["pairedMsa"]), + _request_key(request), searched_msas_from_payload(payload) ) sequence_to_requests: dict[tuple[str, str], list[FeatureRequest]] = {} @@ -557,7 +661,7 @@ def generate(self, requests: Sequence[FeatureRequest]) -> MsaBatchResult: continue for request in matching_requests: try: - payload = self._msa_payload(request, *cached_msas) + payload = self._msa_payload(request, cached_msas) path = self._msa_path(request.name) _write_atomic(path, payload) written.append(MsaArtifact(name=request.name, path=path)) @@ -593,7 +697,7 @@ def generate(self, requests: Sequence[FeatureRequest]) -> MsaBatchResult: for sequence, msas in chunk_msas.items(): for request in sequence_to_requests[(molecule_type, sequence)]: try: - payload = self._msa_payload(request, *msas) + payload = self._msa_payload(request, msas) path = self._msa_path(request.name) _write_atomic(path, payload) written.append(MsaArtifact(name=request.name, path=path)) @@ -667,6 +771,10 @@ def _read_matching_msa( payload.get("pairedMsa"), str ): return None + # Raises on a bundle whose row spans are missing or do not add up, so a + # damaged one is re-searched instead of handed on to a consumer that + # would slice it at the wrong rows. + searched_msas_from_payload(payload) return path, payload except ( KeyError, @@ -766,7 +874,7 @@ def _pack(self, sequences: Sequence[str]) -> tuple[tuple[str, ...], ...]: def _search_chunk( self, sequences: Sequence[str], molecule_type: str = PROTEIN - ) -> dict[str, tuple[str, str]]: + ) -> dict[str, SearchedMsas]: unpaired_databases, paired_database = self._databases(molecule_type) with tempfile.TemporaryDirectory( prefix="alphapulldown_mmseqs_", dir=self._settings.temp_dir @@ -801,24 +909,33 @@ def _search_chunk( result_db = database_root / "result_db" work_dir = database_root / "work" work_dir.mkdir() - msa_db = database_root / "msa_db" - output_dir = database_root / "a3m" - output_dir.mkdir() self._mmseqs.search( query_db, database, result_db, work_dir, self._settings ) - self._mmseqs.result_to_msa(query_db, database, result_db, msa_db) - self._mmseqs.unpack_msa(query_db, msa_db, output_dir) + # One search, formatted twice: headers from one pass, insertions + # from the other. See msa_formats for why neither alone will do. + headers_db = database_root / "headers_db" + headers_dir = database_root / "headers" + headers_dir.mkdir() + self._mmseqs.result_to_msa(query_db, database, result_db, headers_db) + self._mmseqs.unpack_msa(query_db, headers_db, headers_dir) + insertions_db = database_root / "insertions_db" + insertions_dir = database_root / "insertions" + insertions_dir.mkdir() + self._mmseqs.result_to_a3m( + query_db, database, result_db, insertions_db + ) + self._mmseqs.unpack_msa(query_db, insertions_db, insertions_dir) by_database[database.name] = self._read_results( - query_db, output_dir, query_ids, molecule_type + query_db, headers_dir, insertions_dir, query_ids, molecule_type ) results = {} for query_id, sequence in query_ids.items(): - unpaired = _merge_a3ms( + unpaired, unpaired_rows = _merge_a3ms( sequence, [ - by_database[database.name][query_id] + (database.name, by_database[database.name][query_id]) for database in unpaired_databases ], ) @@ -829,13 +946,16 @@ def _search_chunk( if paired_database is not None else "" ) - results[sequence] = (unpaired, paired) + results[sequence] = SearchedMsas( + unpaired=unpaired, paired=paired, unpaired_rows=unpaired_rows + ) return results @staticmethod def _read_results( query_db: Path, - output_dir: Path, + headers_dir: Path, + insertions_dir: Path, query_ids: Mapping[str, str], molecule_type: str = PROTEIN, ) -> dict[str, str]: @@ -851,10 +971,7 @@ def _read_results( str(index): query_id for index, query_id in enumerate(query_ids) } - results = {} - for index, query_id in index_to_query.items(): - if query_id not in query_ids: - continue + def unpacked_records(output_dir: Path, index: str, query_id: str): candidates = ( output_dir / f"{index}.fasta", output_dir / f"{index}.a3m", @@ -868,14 +985,29 @@ def _read_results( "MMseqs2 unpackdb did not produce an alignment for " f"{query_id!r} in {output_dir.parent.name!r}" ) - aligned_fasta = result_path.read_text(encoding="utf-8") - if not _fasta_records(aligned_fasta): + records = _fasta_records(result_path.read_text(encoding="utf-8")) + if not records: raise RuntimeError( "MMseqs2 unpackdb produced no FASTA records for " f"{query_id!r} in {output_dir.parent.name!r}" ) - results[query_id] = _aligned_fasta_to_a3m( - aligned_fasta, query_ids[query_id], molecule_type + return records + + results = {} + for index, query_id in index_to_query.items(): + if query_id not in query_ids: + continue + try: + stitched = stitch_headers_and_insertions( + unpacked_records(headers_dir, index, query_id), + unpacked_records(insertions_dir, index, query_id), + ) + except StitchMismatch as exc: + raise RuntimeError( + f"{query_id!r} in {headers_dir.parent.name!r}: {exc}" + ) from exc + results[query_id] = _stitched_to_a3m( + stitched, query_ids[query_id], molecule_type ) missing_queries = set(query_ids) - set(results) if missing_queries: @@ -886,16 +1018,19 @@ def _read_results( return results def _msa_payload( - self, request: FeatureRequest, unpaired_msa: str, paired_msa: str + self, request: FeatureRequest, msas: SearchedMsas ) -> dict[str, Any]: payload = { - "schemaVersion": 2, + "schemaVersion": 3, "name": request.name, "sequence": request.sequence, - "unpairedMsa": unpaired_msa, - "pairedMsa": paired_msa, - "unpairedDepth": _msa_depth(unpaired_msa), - "pairedDepth": _msa_depth(paired_msa), + "unpairedMsa": msas.unpaired, + "pairedMsa": msas.paired, + "unpairedDepth": _msa_depth(msas.unpaired), + "pairedDepth": _msa_depth(msas.paired), + "unpairedDatabaseRows": [ + {"name": name, "rows": rows} for name, rows in msas.unpaired_rows + ], "provenance": self._cache_signature(request.molecule_type), } # Only non-protein bundles record their molecule type, so a protein bundle is @@ -920,10 +1055,11 @@ def database_value(database: DatabaseSpec) -> dict[str, Any]: if molecule_type == RNA: return { - "schema_version": 1, + "schema_version": 2, "molecule_type": RNA, "mmseqs_identity": self._process_identity(), "search_mode": NUCLEOTIDE_SEARCH_MODE, + "msa_format": _MSA_FORMAT, "e_value": self._settings.rna_e_value, "unpaired_databases": [ database_value(database) @@ -932,9 +1068,10 @@ def database_value(database: DatabaseSpec) -> dict[str, Any]: } signature = { - "schema_version": 4, + "schema_version": 5, "mmseqs_identity": self._process_identity(), "search_mode": self._search_mode(), + "msa_format": _MSA_FORMAT, "e_value": self._settings.e_value, "unpaired_databases": [ database_value(database) @@ -1029,44 +1166,7 @@ def _validate(self, requests: Sequence[FeatureRequest]) -> None: raise ValueError(f"{field_name} requires a non-empty value") def _read_msa(self, request: FeatureRequest) -> dict[str, Any]: - path = self._settings.msa_input_dir / f"{request.name}_mmseqs_msa.json" - try: - encoded = path.read_text(encoding="utf-8") - except OSError as exc: - raise RuntimeError(f"Cannot read MMseqs2 MSA bundle {path}: {exc}") from exc - try: - try: - payload = json.loads(encoded) - except (TypeError, ValueError, json.JSONDecodeError) as exc: - raise _InvalidMsaBundle( - f"Cannot parse MMseqs2 MSA bundle {path}: {exc}" - ) from exc - if not isinstance(payload, dict): - raise _InvalidMsaBundle( - f"MMseqs2 MSA bundle {path} is not a JSON object" - ) - if payload.get("sequence") != request.sequence: - raise _InvalidMsaBundle( - f"MMseqs2 MSA bundle sequence does not match {request.name!r}" - ) - if payload.get("moleculeType", PROTEIN) != request.molecule_type: - raise _InvalidMsaBundle( - "MMseqs2 MSA bundle molecule type does not match " - f"{request.name!r}" - ) - if not isinstance(payload.get("provenance"), dict): - raise _InvalidMsaBundle( - f"MMseqs2 MSA bundle lacks provenance for {request.name!r}" - ) - for key in ("unpairedMsa", "pairedMsa"): - if not isinstance(payload.get(key), str): - raise _InvalidMsaBundle( - f"MMseqs2 MSA bundle lacks {key} for {request.name!r}" - ) - return payload - except _InvalidMsaBundle: - path.unlink(missing_ok=True) - raise + return read_msa_bundle(self._settings.msa_input_dir, request) def _read_matching_artifact( self, request: FeatureRequest, msa_payload: Mapping[str, Any] @@ -1306,33 +1406,40 @@ def _transcribe(sequence: str) -> str: return sequence.replace("T", "U").replace("t", "u") -def _aligned_fasta_to_a3m( - aligned_fasta: str, query_sequence: str, molecule_type: str = PROTEIN +def _stitched_to_a3m( + records: Sequence[tuple[str, str]], + query_sequence: str, + molecule_type: str = PROTEIN, ) -> str: - """Remove query-gap columns while retaining insertions and full headers.""" - from alphafold3.cpp import msa_conversion - - records = _fasta_records(aligned_fasta) + """Validate stitched A3M records against the query and write them out. + + The mode-5 sequences are already A3M against the gapless query, so nothing is + rewritten. What is checked is that every row spans exactly the query: a row + whose match columns number anything else would silently shift every residue + after the discrepancy once AlphaFold reads it as a table. The stitch already + implies this -- mode 2 rows equal mode 5 rows minus insertions -- but a + malformed row should fail here with the query named, not deep in a parser. + """ if not records: - raise ValueError("MMseqs2 aligned FASTA contains no records") - query_alignment = records[0][1] + raise ValueError("MMseqs2 alignment contains no records") normalise = _transcribe if molecule_type == RNA else (lambda sequence: sequence) - if normalise( - query_alignment.replace("-", "").replace(".", "").upper() - ) != normalise(query_sequence.upper()): - raise ValueError( - "MMseqs2 aligned FASTA query does not match its input sequence" - ) + query_row = strip_insertions(records[0][1]) + if normalise(query_row.replace("-", "").upper()) != normalise( + query_sequence.upper() + ): + raise ValueError("MMseqs2 alignment query does not match its input sequence") converted = [] for description, sequence in records: - a3m_sequence = msa_conversion.align_sequence_to_gapless_query( - sequence=sequence, - query_sequence=query_alignment, - ).replace(".", "") + if len(strip_insertions(sequence)) != len(query_sequence): + raise ValueError( + f"MMseqs2 row {description.split()[0]!r} spans " + f"{len(strip_insertions(sequence))} query positions, not " + f"{len(query_sequence)}" + ) if molecule_type == RNA: - a3m_sequence = _transcribe(a3m_sequence) - converted.append(f">{description}\n{a3m_sequence}\n") + sequence = _transcribe(sequence) + converted.append(f">{description}\n{sequence}\n") return "".join(converted) @@ -1344,13 +1451,143 @@ def _normalise_query(a3m: str, query_sequence: str) -> str: return "".join(f">{description}\n{sequence}\n" for description, sequence in records) -def _merge_a3ms(query_sequence: str, a3ms: Sequence[str]) -> str: +def _merge_a3ms( + query_sequence: str, a3ms: Sequence[tuple[str, str]] +) -> tuple[str, tuple[tuple[str, int], ...]]: + """Merge per-database A3Ms in order, and say how many rows each contributed. + + Rows are deduplicated on their aligned residues with the insertions removed. + That is the key this stage used before insertions were recovered, when the two + were the same string, so a merged alignment keeps exactly the rows it kept + then and only their content grows. Keying on the full row instead would keep a + second copy of every hit that two databases aligned with different insertions. + + Databases are appended whole, one after another, so each one's rows are + contiguous and a count is enough to recover them. + """ rows = [("query", query_sequence)] seen = {query_sequence} - for a3m in a3ms: - for _, (description, sequence) in enumerate(_fasta_records(a3m)): - if sequence in seen: + contributed = [] + for database_name, a3m in a3ms: + added = 0 + for description, sequence in _fasta_records(a3m): + key = strip_insertions(sequence) + if key in seen: continue - seen.add(sequence) + seen.add(key) rows.append((description, sequence)) - return "".join(f">{description}\n{sequence}\n" for description, sequence in rows) + added += 1 + contributed.append((database_name, added)) + text = "".join(f">{description}\n{sequence}\n" for description, sequence in rows) + return text, tuple(contributed) + + +def read_msa_bundle( + msa_input_dir: Path, request: FeatureRequest, *, require_row_spans: bool = False +) -> dict[str, Any]: + """Read one request's MSA bundle, deleting it if it is unsafe to use. + + Shared by every finalizer, so each backend refuses the same damaged bundles. + Deleting is what gets a bundle rebuilt: the workflow's Shard completion then no + longer validates, and a repair shard is scheduled. A bundle that is merely + rejected, and left in place, fails the same finalization on every retry. + + ``require_row_spans`` is for consumers that slice the unpaired alignment by + database -- AlphaFold 2 does. A bundle without usable spans is unusable to them, + so it is treated as damaged, not as a failure to report and keep. + """ + path = msa_input_dir / f"{request.name}_mmseqs_msa.json" + try: + encoded = path.read_text(encoding="utf-8") + except OSError as exc: + raise RuntimeError(f"Cannot read MMseqs2 MSA bundle {path}: {exc}") from exc + try: + try: + payload = json.loads(encoded) + except (TypeError, ValueError, json.JSONDecodeError) as exc: + raise _InvalidMsaBundle( + f"Cannot parse MMseqs2 MSA bundle {path}: {exc}" + ) from exc + if not isinstance(payload, dict): + raise _InvalidMsaBundle( + f"MMseqs2 MSA bundle {path} is not a JSON object" + ) + if payload.get("sequence") != request.sequence: + raise _InvalidMsaBundle( + f"MMseqs2 MSA bundle sequence does not match {request.name!r}" + ) + if payload.get("moleculeType", PROTEIN) != request.molecule_type: + raise _InvalidMsaBundle( + "MMseqs2 MSA bundle molecule type does not match " + f"{request.name!r}" + ) + if not isinstance(payload.get("provenance"), dict): + raise _InvalidMsaBundle( + f"MMseqs2 MSA bundle lacks provenance for {request.name!r}" + ) + for key in ("unpairedMsa", "pairedMsa"): + if not isinstance(payload.get(key), str): + raise _InvalidMsaBundle( + f"MMseqs2 MSA bundle lacks {key} for {request.name!r}" + ) + if require_row_spans: + try: + searched_msas_from_payload(payload) + except (KeyError, TypeError, ValueError) as exc: + raise _InvalidMsaBundle( + f"MMseqs2 MSA bundle {path} has no usable per-database row " + f"spans: {exc}" + ) from exc + return payload + except _InvalidMsaBundle: + path.unlink(missing_ok=True) + raise + + +def searched_msas_from_payload(payload: Mapping[str, Any]) -> SearchedMsas: + """Read a bundle back, refusing row spans that do not describe its alignment. + + The spans are what a consumer slices by, so a wrong count does not fail -- it + hands AlphaFold 2 the wrong database's rows as uniref90. Check that they add up. + """ + unpaired = payload["unpairedMsa"] + raw_rows = payload.get("unpairedDatabaseRows") + if not isinstance(raw_rows, list): + raise ValueError("MSA bundle lacks unpairedDatabaseRows") + rows = [] + for entry in raw_rows: + if ( + not isinstance(entry, Mapping) + or not isinstance(entry.get("name"), str) + or not isinstance(entry.get("rows"), int) + or isinstance(entry.get("rows"), bool) + or entry["rows"] < 0 + ): + raise ValueError(f"MSA bundle has a malformed row span: {entry!r}") + rows.append((entry["name"], entry["rows"])) + # The producer always searches the complete named recipe. Counts alone do + # not detect a missing database or a duplicate name that would overwrite an + # earlier span in rows_by_database(). Validate before any finalizer uses it. + molecule_type = payload.get("moleculeType", PROTEIN) + required_names = ( + RNA_DATABASE_NAMES if molecule_type == RNA else UNPAIRED_DATABASE_NAMES + ) + names = tuple(name for name, _ in rows) + if len(names) != len(required_names) or set(names) != set(required_names): + raise ValueError( + "MSA bundle database row spans must name each of " + f"{', '.join(required_names)} exactly once" + ) + if molecule_type == PROTEIN and _msa_depth(payload["pairedMsa"]) == 0: + raise ValueError("Protein MSA bundle has no paired UniProt alignment") + # The query row belongs to no database. An empty alignment is invalid too: + # its depth is zero, so no nonnegative span total can account for its query. + if sum(count for _, count in rows) != _msa_depth(unpaired) - 1: + raise ValueError( + "MSA bundle row spans account for " + f"{sum(count for _, count in rows)} rows but the alignment has " + f"{_msa_depth(unpaired) - 1} besides the query" + ) + return SearchedMsas( + unpaired=unpaired, paired=payload["pairedMsa"], unpaired_rows=tuple(rows) + ) diff --git a/alphapulldown/objects.py b/alphapulldown/objects.py index d9e61b23..40409060 100644 --- a/alphapulldown/objects.py +++ b/alphapulldown/objects.py @@ -44,6 +44,22 @@ def _query_only_stockholm(sequence: str, query_id: str = "query") -> str: ) +def add_template_feature_defaults( + feature_dict: Dict[str, Any], sequence: str +) -> None: + """Fill the two template features native AlphaFold 2 features lack. + + The mmseqs2 path produces ``template_confidence_scores`` and + ``template_release_date``; jackhmmer features do not. Every AlphaFold 2 + feature source adds them here, so pickles from any source carry the same + keys and a multimer built from mixed sources does not fail on a missing one. + """ + if feature_dict.get("template_confidence_scores") is None: + feature_dict["template_confidence_scores"] = np.array([[1] * len(sequence)]) + if feature_dict.get("template_release_date") is None: + feature_dict["template_release_date"] = np.array(["none"]) + + def _ensure_identifier_feature_arrays( feature_dict: Dict[str, np.ndarray], feature_groups: Tuple[Tuple[str, Tuple[str, ...]], ...], @@ -226,16 +242,8 @@ def make_features( fasta_file, self._uniprot_runner, msa_output_dir, use_precomputed_msa ) self.feature_dict.update(pairing_results) - - # Add extra features to make it compatible with pickle features obtaiend from mmseqs2 - template_confidence_scores = self.feature_dict.get('template_confidence_scores', None) - template_release_date = self.feature_dict.get('template_release_date', None) - if template_confidence_scores is None: - self.feature_dict.update( - {'template_confidence_scores': np.array([[1] * len(self.sequence)])} - ) - if template_release_date is None: - self.feature_dict.update({"template_release_date" : np.array(['none'])}) + + add_template_feature_defaults(self.feature_dict, self.sequence) # post processing if (not save_msa) and (not use_precomputed_msa): diff --git a/alphapulldown/scripts/_mmseqs2_cli.py b/alphapulldown/scripts/_mmseqs2_cli.py index babe96e0..409b3b22 100644 --- a/alphapulldown/scripts/_mmseqs2_cli.py +++ b/alphapulldown/scripts/_mmseqs2_cli.py @@ -110,6 +110,16 @@ def define_msa_search_flags( 8, "CPU threads for MMseqs2 operations.", ) + _define_once( + "mmseqs_db_load_mode", + flags.DEFINE_integer, + None, + "How MMseqs2 reads the target database: 0 auto, 1 fread, 2 mmap, " + "3 mmap+touch. Left unset MMseqs2 chooses, which reads the whole target " + "database into RSS; 2 memory-maps it instead and lowers peak memory. It " + "changes memory behaviour only, never the alignment, so it is not part of " + "the MSA cache identity and switching it reuses existing bundles.", + ) _define_once( "mmseqs_rna_e_value", flags.DEFINE_float, @@ -160,6 +170,13 @@ def define_msa_search_flags( def define_template_provenance_flags() -> None: + _define_once( + "template_pdb70_database_id", + flags.DEFINE_string, + None, + "Immutable identity of the PDB70 build used with AF2 --use_hhsearch. " + "Change this identity whenever PDB70 is rebuilt, even at the same path.", + ) _define_once( "template_seqres_database_id", flags.DEFINE_string, @@ -300,5 +317,23 @@ def always_required_msa_flag_names() -> tuple[str, ...]: return required_msa_flag_names(molecule_types=()) -def required_template_flag_names() -> tuple[str, ...]: - return ("template_seqres_database_id", "template_mmcif_database_id") +def required_template_flag_names( + *, data_pipeline: str = "alphafold3", use_hhsearch: bool = False +) -> tuple[str, ...]: + database = ( + "template_pdb70_database_id" + if data_pipeline == "alphafold2" and use_hhsearch + else "template_seqres_database_id" + ) + return (database, "template_mmcif_database_id") + + +def require_template_flags(flag_values: flags.FlagValues) -> None: + """Validate identities for the databases the selected template search reads.""" + required = required_template_flag_names( + data_pipeline=_flag_value(flag_values, "data_pipeline"), + use_hhsearch=bool(_flag_value(flag_values, "use_hhsearch")), + ) + missing = [name for name in required if not str(_flag_value(flag_values, name) or "").strip()] + if missing: + raise ValueError("Template finalization requires " + ", ".join(f"--{name}" for name in missing)) diff --git a/alphapulldown/scripts/compare_msa_backends.py b/alphapulldown/scripts/compare_msa_backends.py index 0c13f09b..a06f0212 100644 --- a/alphapulldown/scripts/compare_msa_backends.py +++ b/alphapulldown/scripts/compare_msa_backends.py @@ -13,10 +13,17 @@ flags.DEFINE_string( - "reference_dir", None, "Directory of native/jackhmmer AF3 JSON artifacts." + "reference_dir", None, "Directory of native/jackhmmer feature artifacts." ) -flags.DEFINE_string("candidate_dir", None, "Directory of MMseqs2 AF3 JSON artifacts.") +flags.DEFINE_string("candidate_dir", None, "Directory of MMseqs2 feature artifacts.") flags.DEFINE_string("output_path", None, "JSON report path.") +flags.DEFINE_enum( + "artifact_format", + "af3_json", + ["af3_json", "af2_pickle"], + "af3_json: _af3_input.json[.xz]. af2_pickle: .pkl[.xz], the " + "MonomericObject pickles AlphaFold 2 reads.", +) FLAGS = flags.FLAGS @@ -137,16 +144,138 @@ def mean(key: str, backend: str) -> float: } +def _af2_artifacts(directory: Path) -> dict[str, Path]: + result = {} + for path in sorted(directory.glob("*.pkl*")): + filename = path.name + for suffix in (".pkl.xz", ".pkl"): + if filename.endswith(suffix): + result[filename[: -len(suffix)]] = path + break + return result + + +def _af2_side(features: dict) -> dict: + """What one AlphaFold 2 feature set offers the model, measured.""" + import numpy as np + + # The alphabet AlphaFold 2 encodes MSAs in, spelled out without importing it. + from alphapulldown.utils.af2_to_af3_msa import AF2_ID_TO_A3M + + msa = np.asarray(features["msa"]) + length = int(msa.shape[1]) + unpaired = "".join( + f">row{index}\n{''.join(AF2_ID_TO_A3M[int(i)] for i in row)}\n" + for index, row in enumerate(msa) + ) + deletions = np.asarray(features["deletion_matrix_int"]) + species = { + value.decode() if isinstance(value, bytes) else str(value) + for value in features.get("msa_species_identifiers_all_seq", []) + } + species.discard("") + templates = [ + name for name in features.get("template_domain_names", []) + if (name.decode() if isinstance(name, bytes) else str(name)) + ] + return { + "unpaired": measure_a3m(unpaired, query_length=length), + "unpaired_neff": neff(unpaired), + # Rows carrying at least one insertion: all zero for a local MMseqs2 + # alignment built from result2msa mode 2 alone. + "rows_with_insertions": int((deletions.sum(axis=1) > 0).sum()), + "paired_depth": int(np.asarray(features.get("msa_all_seq", msa[:1])).shape[0]), + # Pairing needs a species in common; distinct labels are what it has to use. + "paired_species": len(species), + "template_count": len(templates), + } + + +def compare_af2_directories(reference_dir: Path, candidate_dir: Path) -> list[dict]: + """Paired measurements of two directories of AlphaFold 2 feature pickles. + + No homolog overlap: a pickle stores its alignment as integer rows without the + sequence headers, so there is no accession to match on, and residue strings + are not a substitute -- two backends align the same homolog over different + extents. Compare the raw alignments for overlap; this compares what the + model is given. + """ + from alphapulldown.utils.lightweight_pickles import ( + extract_feature_dict, + load_lightweight_pickle, + ) + + references = _af2_artifacts(reference_dir) + candidates = _af2_artifacts(candidate_dir) + missing = sorted(references.keys() ^ candidates.keys()) + if missing: + raise ValueError("Artifact sets differ: " + ", ".join(missing)) + rows = [] + for name in sorted(references): + reference = load_lightweight_pickle(references[name]) + candidate = load_lightweight_pickle(candidates[name]) + if reference.sequence != candidate.sequence: + raise ValueError(f"Sequence mismatch for {name!r}") + rows.append( + { + "name": name, + "reference_path": str(references[name]), + "candidate_path": str(candidates[name]), + "reference": _af2_side(extract_feature_dict(reference)), + "candidate": _af2_side(extract_feature_dict(candidate)), + } + ) + return rows + + +def summarize_af2(rows: list[dict]) -> dict: + if not rows: + return {"protein_count": 0} + + def mean(side: str, *path: str) -> float: + total = 0.0 + for row in rows: + value = row[side] + for key in path: + value = value[key] + total += value + return total / len(rows) + + summary = {"protein_count": len(rows)} + for side in ("reference", "candidate"): + summary.update( + { + f"mean_{side}_unpaired_depth": mean(side, "unpaired", "depth"), + f"mean_{side}_unpaired_neff": mean(side, "unpaired_neff"), + f"mean_{side}_rows_with_insertions": mean(side, "rows_with_insertions"), + f"mean_{side}_paired_depth": mean(side, "paired_depth"), + f"mean_{side}_paired_species": mean(side, "paired_species"), + f"mean_{side}_template_count": mean(side, "template_count"), + } + ) + return summary + + def main(argv) -> None: del argv - proteins = compare_directories(Path(FLAGS.reference_dir), Path(FLAGS.candidate_dir)) + if FLAGS.artifact_format == "af2_pickle": + proteins = compare_af2_directories( + Path(FLAGS.reference_dir), Path(FLAGS.candidate_dir) + ) + summary = summarize_af2(proteins) + else: + proteins = compare_directories( + Path(FLAGS.reference_dir), Path(FLAGS.candidate_dir) + ) + summary = summarize(proteins) report = { "schemaVersion": 1, "warning": ( "MSA/template metrics are diagnostic only; run matched inference and " "DockQ against experimental references before claiming accuracy equivalence." ), - "summary": summarize(proteins), + "artifactFormat": FLAGS.artifact_format, + "summary": summary, "proteins": proteins, } Path(FLAGS.output_path).write_text( diff --git a/alphapulldown/scripts/create_batch_features.py b/alphapulldown/scripts/create_batch_features.py index 84c4f749..25735216 100644 --- a/alphapulldown/scripts/create_batch_features.py +++ b/alphapulldown/scripts/create_batch_features.py @@ -93,7 +93,9 @@ def main(argv) -> None: template_mmcif_database_id=FLAGS.template_mmcif_database_id, ), mmseqs_process=SubprocessMmseqsProcess( - FLAGS.mmseqs_binary_path, gpu=FLAGS.mmseqs_use_gpu + FLAGS.mmseqs_binary_path, + gpu=FLAGS.mmseqs_use_gpu, + db_load_mode=FLAGS.mmseqs_db_load_mode, ), af3_pipeline=pipeline, ).generate(requests) diff --git a/alphapulldown/scripts/create_batch_msas.py b/alphapulldown/scripts/create_batch_msas.py index fe61ddeb..4ed43be0 100644 --- a/alphapulldown/scripts/create_batch_msas.py +++ b/alphapulldown/scripts/create_batch_msas.py @@ -57,7 +57,9 @@ def main(argv) -> None: result = MsaBatch( settings=settings, mmseqs_process=SubprocessMmseqsProcess( - FLAGS.mmseqs_binary_path, gpu=FLAGS.mmseqs_use_gpu + FLAGS.mmseqs_binary_path, + gpu=FLAGS.mmseqs_use_gpu, + db_load_mode=FLAGS.mmseqs_db_load_mode, ), ).generate(requests) logging.info( diff --git a/alphapulldown/scripts/create_individual_features.py b/alphapulldown/scripts/create_individual_features.py index 8d433acd..f1c3f8ac 100644 --- a/alphapulldown/scripts/create_individual_features.py +++ b/alphapulldown/scripts/create_individual_features.py @@ -21,13 +21,15 @@ from colabfold.utils import DEFAULT_API_SERVER # AlphaFold2 imports -from alphafold.data import templates from alphafold.data.pipeline import DataPipeline as AF2DataPipeline -from alphafold.data.tools import hmmsearch, hhsearch # AlphaPulldown helpers from alphapulldown.utils.create_custom_template_db import create_db from alphapulldown.objects import MonomericObject +from alphapulldown.af2_feature_finalizer import ( + Af2TemplateStackSettings, + build_af2_template_stack, +) from alphapulldown.utils.file_handling import ( iter_seqs, parse_csv_file, @@ -395,29 +397,35 @@ def get_af3_feature_metadata(chain_kinds, *, skip_msa, flag_values=None): # =================== AlphaFold 2 Feature Creation =================== +def af2_template_stack_settings(): + """The AF2 template stack as this run's flags describe it, mutating nothing. + + Paths not given explicitly come from --data_dir, the same defaults + create_arguments() would have written into FLAGS. + """ + def path(flag_name, database_key): + explicit = getattr(FLAGS, flag_name) + if explicit: + return explicit + return get_database_path(database_key) if FLAGS.data_dir else None + + return Af2TemplateStackSettings( + template_mmcif_dir=path("template_mmcif_dir", "template_mmcif_dir"), + max_template_date=FLAGS.max_template_date, + kalign_binary_path=FLAGS.kalign_binary_path, + obsolete_pdbs_path=path("obsolete_pdbs_path", "obsolete_pdbs"), + use_hhsearch=FLAGS.use_hhsearch, + hmmsearch_binary_path=FLAGS.hmmsearch_binary_path, + hmmbuild_binary_path=FLAGS.hmmbuild_binary_path, + pdb_seqres_database_path=path("pdb_seqres_database_path", "pdb_seqres"), + hhsearch_binary_path=FLAGS.hhsearch_binary_path, + pdb70_database_path=path("pdb70_database_path", "pdb70"), + ) + + def _create_af2_template_stack(): """Create the AF2 template searcher and featurizer.""" - if FLAGS.use_hhsearch: - template_searcher = hhsearch.HHSearch( - binary_path=FLAGS.hhsearch_binary_path, databases=[FLAGS.pdb70_database_path] - ) - template_featuriser = templates.HhsearchHitFeaturizer( - mmcif_dir=FLAGS.template_mmcif_dir, max_template_date=FLAGS.max_template_date, - max_hits=20, kalign_binary_path=FLAGS.kalign_binary_path, - release_dates_path=None, obsolete_pdbs_path=FLAGS.obsolete_pdbs_path - ) - else: - template_featuriser = templates.HmmsearchHitFeaturizer( - mmcif_dir=FLAGS.template_mmcif_dir, max_template_date=FLAGS.max_template_date, - max_hits=20, kalign_binary_path=FLAGS.kalign_binary_path, - obsolete_pdbs_path=FLAGS.obsolete_pdbs_path, release_dates_path=None - ) - template_searcher = hmmsearch.Hmmsearch( - binary_path=FLAGS.hmmsearch_binary_path, - hmmbuild_binary_path=FLAGS.hmmbuild_binary_path, - database_path=FLAGS.pdb_seqres_database_path - ) - return template_searcher, template_featuriser + return build_af2_template_stack(af2_template_stack_settings()) def create_pipeline_af2(): diff --git a/alphapulldown/scripts/finalize_batch_features.py b/alphapulldown/scripts/finalize_batch_features.py index 6ac0024c..27f29dfc 100644 --- a/alphapulldown/scripts/finalize_batch_features.py +++ b/alphapulldown/scripts/finalize_batch_features.py @@ -1,17 +1,27 @@ #!/usr/bin/env python3 -"""CPU-only native AF3 template search and feature finalization stage.""" +"""CPU-only template search and feature finalization for local MMseqs2 bundles. + +Reads the MSA bundles the search stage wrote and publishes standard features for +either backend: AlphaFold 3 input JSON, or AlphaFold 2 MonomericObject pickles. +""" from __future__ import annotations import os -# AF3 imports JAX transitively; this CPU stage must never initialize a GPU. +# AF3 imports JAX transitively, and so does alphapulldown.objects via ColabFold; +# this CPU stage must never initialize a GPU. os.environ["JAX_PLATFORMS"] = "cpu" from pathlib import Path from absl import app, flags, logging +from alphapulldown.af2_feature_finalizer import ( + Af2FeatureFinalizationSettings, + Af2FeatureFinalizer, + build_af2_template_stack, +) from alphapulldown.feature_batch import ( MOLECULE_TYPES, PROTEIN, @@ -22,8 +32,9 @@ from alphapulldown.scripts import create_individual_features as legacy_features from alphapulldown.scripts._mmseqs2_cli import ( define_template_provenance_flags, - required_template_flag_names, + require_template_flags, ) +from alphapulldown.utils import save_meta_data flags.DEFINE_string("msa_input_dir", None, "Directory containing MMseqs2 MSA bundles.") @@ -34,14 +45,88 @@ def main(argv) -> None: del argv - if FLAGS.data_pipeline != "alphafold3": - raise ValueError("MMseqs2 MSA finalization requires --data_pipeline=alphafold3") if FLAGS.keep_msas or FLAGS.skip_msa or FLAGS.path_to_mmt or FLAGS.use_mmseqs2: raise ValueError( "MMseqs2 MSA finalization cannot be combined with --keep_msas, " "--skip_msa, --path_to_mmt, or --use_mmseqs2" ) + require_template_flags(FLAGS) + if FLAGS.data_pipeline == "alphafold2": + result = _finalize_alphafold2() + backend = "AF2" + else: + result = _finalize_alphafold3() + backend = "AF3" + logging.info( + "%s feature finalization: %d written, %d reused, %d failed", + backend, + len(result.written), + len(result.reused), + len(result.failures), + ) + if result.failures: + detail = ", ".join( + f"{failure.name} ({failure.error})" for failure in result.failures + ) + raise RuntimeError( + f"{backend} feature finalization failed for {len(result.failures)} " + f"chain(s): {detail}" + ) + + +def af2_template_metadata(stack) -> dict: + """Provenance for the resources an AlphaFold 2 finalization actually uses. + + Not the run's whole flag set: the jackhmmer and HHblits binary flags default to + whatever is on PATH, so recording them would claim this MSA came from tools + that never touched it. The MSA's own provenance is the bundle's, added by the + finalizer. Only the template stack, which does run here, is recorded. + """ + used = { + "template_mmcif_dir": stack.template_mmcif_dir, + "obsolete_pdbs_path": stack.obsolete_pdbs_path, + "kalign_binary_path": stack.kalign_binary_path, + "max_template_date": stack.max_template_date, + "data_pipeline": "alphafold2", + } + if stack.use_hhsearch: + used["hhsearch_binary_path"] = stack.hhsearch_binary_path + used["pdb70_database_path"] = stack.pdb70_database_path + else: + used["hmmsearch_binary_path"] = stack.hmmsearch_binary_path + used["hmmbuild_binary_path"] = stack.hmmbuild_binary_path + used["pdb_seqres_database_path"] = stack.pdb_seqres_database_path + return save_meta_data.get_meta_dict(used) + +def _finalize_alphafold2(): + # Explicit settings, as for AlphaFold 3 below: paths come from --data_dir + # without create_arguments() rewriting the global FLAGS. + stack = legacy_features.af2_template_stack_settings() + template_searcher, template_featurizer = build_af2_template_stack(stack) + # Every molecule type the search stage can produce is read, so an RNA chain + # fails here by name, with the reason, rather than as a missing bundle. + requests = feature_requests_from_fastas( + FLAGS.fasta_paths, molecule_types=MOLECULE_TYPES + ) + return Af2FeatureFinalizer( + settings=Af2FeatureFinalizationSettings( + output_dir=Path(FLAGS.output_dir), + msa_input_dir=Path(FLAGS.msa_input_dir), + max_template_date=FLAGS.max_template_date, + template_seqres_database_id=FLAGS.template_seqres_database_id, + template_mmcif_database_id=FLAGS.template_mmcif_database_id, + template_searcher=stack.searcher_name, + template_pdb70_database_id=FLAGS.template_pdb70_database_id, + compress=FLAGS.compress_features, + base_metadata=af2_template_metadata(stack), + ), + template_searcher=template_searcher, + template_featurizer=template_featurizer, + ).generate(requests) + + +def _finalize_alphafold3(): # No create_arguments() here: it worked by mutating the global FLAGS and the two # calls below then read that mutation back, so this stage depended on call order # across a script boundary. The settings resolve the same paths explicitly. @@ -59,7 +144,7 @@ def main(argv) -> None: skip_msa=True, flag_values=settings.flag_values_with_resolved_paths(FLAGS.flag_values_dict()), ) - result = FeatureFinalizer( + return FeatureFinalizer( settings=FeatureFinalizationSettings( output_dir=Path(FLAGS.output_dir), msa_input_dir=Path(FLAGS.msa_input_dir), @@ -71,19 +156,6 @@ def main(argv) -> None: ), af3_pipeline=pipeline, ).generate(requests) - logging.info( - "AF3 feature finalization: %d written, %d reused, %d failed", - len(result.written), - len(result.reused), - len(result.failures), - ) - if result.failures: - detail = ", ".join( - f"{failure.name} ({failure.error})" for failure in result.failures - ) - raise RuntimeError( - f"AF3 feature finalization failed for {len(result.failures)} chain(s): {detail}" - ) if __name__ == "__main__": @@ -94,7 +166,7 @@ def main(argv) -> None: "output_dir", "data_dir", "max_template_date", - *required_template_flag_names(), + "template_mmcif_database_id", ] ) app.run(main) diff --git a/alphapulldown/utils/msa_formats.py b/alphapulldown/utils/msa_formats.py new file mode 100644 index 00000000..4fafb74c --- /dev/null +++ b/alphapulldown/utils/msa_formats.py @@ -0,0 +1,91 @@ +"""Turn MMseqs2 output into A3M that keeps both its headers and its insertions. + +No AlphaFold dependency of any kind. The search stage used to convert results +with ``alphafold3.cpp.msa_conversion``, and the AlphaFold 2 image installs +AlphaPulldown without the ``alphafold3`` extra, so the shared stage imported +cleanly there and then died on the first search result. + +The formats. ``mmseqs result2msa`` offers several, and none gives both things an +AlphaFold alignment needs. Measured on the pinned build +(8cc5ce367b5638c4306c2d7cfc652dd099a4643f), with a target carrying a deliberate +four-residue insertion:: + + mode 2 >sp|P00002|INSERT_MOUSE has a 4-residue insertion OS=Mus musculus + MKTAYIAKQRQISFVKSHFSRQLEE... <- the WWWW is gone + mode 5 >P00002 + MKTAYIAKQRQISFVKSHwwwwFSRQLEE... <- kept, as an A3M insertion + +Mode 2 keeps the full header and drops every column the query does not span, so +an alignment built from it alone has no insertions and AlphaFold derives an +all-zero deletion matrix from it. That is not a small detail: against a real +586-residue query, 98 of 120 small_bfd hits (81.7%) and 712 of 824 uniprot hits +(86.4%) carry insertions, 13035 residues of them on uniprot alone. + +Mode 5 keeps the insertions and cuts the header to the database key. How much +that loses depends on the FASTA the database was built from: small_bfd headers +are a single token and survive whole, but uniprot's ``sp|P83570|GWA_SEPOF …`` +becomes ``P83570`` -- and AlphaFold 2 reads the species out of the long form, and +species is what pairs chains in a complex. The same holds for nucleotide +searches, so RNA takes the same route. + +So both are run over one search result and joined by +:func:`stitch_headers_and_insertions`. The second pass costs little: 2 s against +a 947 s search on small_bfd, 13 s against 3739 s on uniprot, roughly 16 ms a hit. +""" + +from __future__ import annotations + +from typing import Sequence + + +def strip_insertions(a3m_row: str) -> str: + """Drop the insertion residues, leaving one column per query position.""" + return "".join(residue for residue in a3m_row if not residue.islower()) + + +class StitchMismatch(ValueError): + """Two result2msa passes over one result set disagreed about their rows.""" + + +def stitch_headers_and_insertions( + headers_from: Sequence[tuple[str, str]], + insertions_from: Sequence[tuple[str, str]], +) -> list[tuple[str, str]]: + """Join mode-2 headers to mode-5 sequences, verifying the join row by row. + + Both arguments are ``(description, sequence)`` records read from one search + result formatted twice: ``headers_from`` carries the full database headers and + no insertions, ``insertions_from`` carries the insertions and a bare accession. + MMseqs2 emits both in result order, so they line up positionally. + + Positional joins are exactly the kind that rot silently, so this one is + checked rather than trusted: removing the insertions from a mode-5 row has to + reproduce the mode-2 row character for character, on every row. If a future + MMseqs2 ever reorders, filters or realigns one pass and not the other, this + raises instead of emitting a chimeric alignment in which headers describe the + wrong sequences -- which for the paired database would mean pairing chains by + the wrong species, a wrong answer that looks entirely plausible. + + Verified against real data: 120/120 rows on small_bfd, and 31/31 on a + synthetic set built with random insertions and deletions. + """ + if len(headers_from) != len(insertions_from): + raise StitchMismatch( + "the two result2msa passes returned different row counts " + f"({len(headers_from)} with headers, {len(insertions_from)} with " + "insertions); they cannot describe the same search result" + ) + stitched = [] + for index, ((description, aligned), (_, with_insertions)) in enumerate( + zip(headers_from, insertions_from) + ): + if strip_insertions(with_insertions) != aligned: + raise StitchMismatch( + f"row {index} differs between the two result2msa passes: " + f"{strip_insertions(with_insertions)!r} from the insertion pass " + f"does not match {aligned!r} from the header pass. The two are " + "no longer in the same order, so headers cannot be trusted to " + "describe these sequences" + ) + stitched.append((description, with_insertions)) + return stitched diff --git a/docs/mmseqs2_rna.md b/docs/mmseqs2_rna.md index 94f74c85..8da2aee1 100644 --- a/docs/mmseqs2_rna.md +++ b/docs/mmseqs2_rna.md @@ -1,9 +1,10 @@ -# Local MMseqs2 features (AlphaFold 3) +# Local MMseqs2 features (AlphaFold 2 and 3) An alternative to the per-protein jackhmmer/HHblits MSA search: proteins are split into -bounded shards searched with MMseqs2, and a separate CPU stage runs AlphaFold 3's own -template search and writes one standard AF3 JSON per chain. Off by default. Existing -AlphaFold 2 feature generation and the remote `--use_mmseqs2` path are untouched. +bounded shards searched with MMseqs2, and a separate CPU stage turns each chain's +alignment into standard features — an AF3 JSON with AlphaFold 3's own template search, +or an AF2 `MonomericObject` pickle; see [AlphaFold 2](#alphafold-2) below. Off by +default. Native feature generation and the remote `--use_mmseqs2` path are untouched. RNA chains can use the same path once the RNA databases are configured; see [RNA chains](#rna-chains) below. @@ -131,6 +132,84 @@ Useful flags: `--mmseqs_rna_e_value` (default `1e-3`) and `--mmseqs__max_sequences` (default `10000` per RNA database), both matching AlphaFold 3's own settings. +## AlphaFold 2 + +The search is the same; only finalization differs. Pass `--data_pipeline alphafold2` to +`finalize_batch_features.py` and it writes `.pkl` (or `.pkl.xz` with +`--compress_features`), the pickle the AlphaFold 2 backend reads: + +```bash +python -m alphapulldown.scripts.finalize_batch_features \ + --data_pipeline alphafold2 --fasta_paths complex.fasta \ + --msa_input_dir msas/ --output_dir features/ --data_dir /db/alphafold2 \ + --max_template_date 2026-08-01 \ + --template_seqres_database_id pdb-seqres-2026-08 --template_mmcif_database_id pdb-mmcif-2026-08 +``` + +Templates come from the AlphaFold 2 database tree under `--data_dir` (`pdb_seqres`, +`pdb_mmcif`), searched with hmmsearch, or with hhsearch against PDB70 under +`--use_hhsearch`. The MSA databases are the MMseqs2 ones the search stage used. + +For HHsearch, replace `--template_seqres_database_id` in the example with +`--template_pdb70_database_id pdb70-2026-08`. The selected database identity and +the mmCIF identity are required. Change the relevant identity whenever that +database is rebuilt, even if its path stays the same. This regenerates features +while reusing the existing MSA bundle; changing an unused database does not +invalidate features. Existing HHsearch pickles without a PDB70 identity are +regenerated once. The hmmsearch and AF3 cache identities are unchanged. + +The features are built the way native AlphaFold 2 builds them from jackhmmer: + +- uniref90 capped at 10 000 rows and MGnify at 501, counting the query as AlphaFold 2 + does; small BFD uncapped +- merged in AlphaFold 2's order, UniRef90, BFD, MGnify — row order matters, since it + samples its MSA from the top +- templates searched from UniRef90 **alone**, never from the merged alignment; the + bundle records which rows each database contributed so this is possible +- pairing features (`*_all_seq`) from the separate UniProt search, whose headers carry + the species AlphaFold 2 pairs chains by + +What differs, and why: + +- **The recipe is `reduced_dbs`.** There is no BFD/UniRef30 HHblits arm, so compare + against `--db_preset reduced_dbs`, not `full_dbs`. +- **Caps apply after cross-database deduplication**, where native AlphaFold 2 caps raw + hits first. This only affects rows two databases both found. +- **The template profile has no insert columns.** A3M insertions are per row and not + aligned to each other, so they cannot be turned back into Stockholm columns; the match + columns, which decide the profile's states, are the same. +- **Accession identifiers are filled in** from the UniProt headers, where native + features leave them empty. Nothing on this path queries UniProt over the network. + +The pickles carry the same feature keys as native ones plus those two accession arrays, +and assemble into multimers alongside pickles from other sources. RNA and DNA chains are +refused: AlphaFold 2 has no MSA features for them. + +### Measured against native AlphaFold 2 + +32 monomers spread over the quartiles of their native MSA depth, plus 12 heterodimers +released after AF2-multimer's training cutoff, featurized natively with `reduced_dbs` and +through this path, with the same databases and templates up to 2021-09-30: + +| median, unless stated | native | local, GPU search | local, CPU search | +|---|---|---|---| +| MSA depth, shallowest quartile | 52 | 29 | 28 | +| MSA depth, deepest quartile | 12 247 | 11 756 | 5 181 | +| Neff, all monomers | 778 | 627 | 572 | +| templates per chain | 16 | 16 | 15 | +| AF2-multimer DockQ, top-ranked, mean of 12 | 0.59 | 0.56 | 0.56 | +| acceptable interfaces (DockQ ≥ 0.23) | 9 / 12 | 9 / 12 | 9 / 12 | + +- The MSAs are shallower, most on the shallowest families, as for AlphaFold 3. A GPU + search recovers about three quarters of native's unpaired hits. +- A CPU search, at MMseqs2's default sensitivity, finds far fewer distant hits than the + GPU prefilter on deep families, without changing DockQ here. +- One interface (9HMX) lost about 0.3 DockQ against native; the other eleven moved by + less than 0.1. +- Finalization is dominated by template featurization: median ~1 GB and 2 min per chain, + but up to 19 GB and 90 min, set by which structures the templates come from rather + than by chain length or MSA depth. + ## The binary Both maintained prediction images bundle the same pinned MMseqs2-GPU build at diff --git a/test/cluster/check_alphafold2_predictions.py b/test/cluster/check_alphafold2_predictions.py index 0b7423f9..a9a7715f 100755 --- a/test/cluster/check_alphafold2_predictions.py +++ b/test/cluster/check_alphafold2_predictions.py @@ -810,5 +810,195 @@ def test_issue_614_precomputed_mmseqs_features_enable_af2_multimer_inference(sel f"Expected AF2 ipTM > 0.6 from precomputed MMseq features, got {result_payload['iptm']}", ) + +MMSEQS_DATABASE_DIR = Path( + os.getenv("MMSEQS_DATABASE_DIR", "/g/alphafold/AlphaFold_DBs/mmseqs") +) +# GPU-padded builds of the AlphaFold 3.0.0 FASTAs (scripts/setup_databases.sh --mmseqs), +# each named _gpu, with the identifiers the AlphaFold 2 benchmark used. +LOCAL_MMSEQS_DATABASE_IDS = { + "uniref90": "uniref90-2022_05-padded", + "mgnify": "mgy_clusters-2022_05-padded", + "small_bfd": "small-bfd-padded", + "uniprot": "uniprot_all-2021_04-padded", +} +# A seeded random 90-mer with no homologs anywhere. In the Snakemake end-to-end run the +# local path returned only the query for it. +ORPHAN_SEQUENCE = ( + "MYNARDGTQMSKFWKTDQPEWVTSYVYMRCQGQFWPAKCVIWGGAYNDV" + "HSGVVSGENWKIGSTWMNISMVDQDMITGQAMWSVRNVLFC" +) + + +class TestLocalMmseqsAgainstRemote(_TestBase): + """Opt-in: AF2 features from the local MMseqs2 path against the remote ColabFold API. + + The two search different databases -- ColabFold's UniRef30 and environmental sets + remotely; UniRef90, MGnify, small BFD and UniProt locally -- so this asserts + agreement, not equality. The bands come from a 32-monomer benchmark: on families + with hundreds of hits or more, local over remote depth ran 0.26-3.7 (one outlier at + 0.03), and Neff alike. Needs network access to the ColabFold API, a GPU-capable + MMseqs2 build, and ~200 GB of host RAM, because the search reads every padded + database in full: + + RUN_MMSEQS_FUNCTIONAL_TESTS=1 MMSEQS_INTEGRATION_BINARY=/path/to/mmseqs \\ + python test/cluster/run_alphafold2_predictions.py \\ + -k TestLocalMmseqsAgainstRemote --constraint "" --mem 200G --time 06:00:00 + """ + + # A deep family with hundreds of structures, and a moderate one from the + # benchmark (1517 rows remotely, 1264 locally). + FAMILY_CHAINS = ("P61626", "O31718") + MAX_TEMPLATE_DATE = "2024-05-02" + RATIO_BAND = (0.2, 5.0) + + def _require_local_mmseqs_environment(self) -> Path: + skip_reason = _mmseqs_functional_test_skip_reason() + if skip_reason: + self.skipTest(skip_reason) + binary = os.getenv("MMSEQS_INTEGRATION_BINARY") + if not binary or not Path(binary).is_file(): + self.skipTest("Set MMSEQS_INTEGRATION_BINARY to a GPU-capable MMseqs2 build.") + missing = [ + name + for name in LOCAL_MMSEQS_DATABASE_IDS + if not (MMSEQS_DATABASE_DIR / f"{name}_gpu.dbtype").is_file() + ] + if missing: + self.skipTest( + f"Padded MMseqs2 databases missing under {MMSEQS_DATABASE_DIR}: " + + ", ".join(missing) + ) + return Path(binary) + + def _run_step(self, label: str, args: list[str]) -> None: + env = _af2_subprocess_env() + # The scripts default their template tools (kalign, hmmsearch, hmmbuild) to + # whatever is first on PATH. Put this interpreter's environment first, so a + # job launched from another environment's shell still gets the tools installed + # alongside AlphaPulldown; otherwise kalign resolves to None and every chain + # fails at template realignment. + env["PATH"] = os.pathsep.join( + [str(Path(sys.executable).parent), env.get("PATH", "")] + ) + res = subprocess.run( + [sys.executable, *args], capture_output=True, text=True, env=env + ) + self.assertEqual( + res.returncode, + 0, + f"{label} failed.\nSTDOUT:\n{res.stdout}\nSTDERR:\n{res.stderr}", + ) + + def test_local_mmseqs_features_agree_with_remote(self): + binary = self._require_local_mmseqs_environment() + orphan = self.output_dir / "orphan.fasta" + orphan.write_text(f">orphan\n{ORPHAN_SEQUENCE}\n", encoding="utf-8") + fasta_paths = ",".join( + [ + str(self.test_data_dir / "fastas" / f"{name}.fasta") + for name in self.FAMILY_CHAINS + ] + + [str(orphan)] + ) + remote_dir = self.output_dir / "remote" + local_dir = self.output_dir / "local" + msa_dir = self.output_dir / "msas" + scripts = self.script_create_features.parent + shared = [ + f"--fasta_paths={fasta_paths}", + f"--data_dir={DATA_DIR}", + f"--max_template_date={self.MAX_TEMPLATE_DATE}", + "--compress_features=True", + ] + + self._run_step( + "Remote MMseqs2 features", + [ + str(self.script_create_features), + *shared, + f"--output_dir={remote_dir}", + "--use_mmseqs2=True", + "--data_pipeline=alphafold2", + "--skip_existing=False", + ], + ) + self._run_step( + "Local MMseqs2 search", + [ + str(scripts / "create_batch_msas.py"), + f"--fasta_paths={fasta_paths}", + f"--msa_output_dir={msa_dir}", + f"--summary_path={self.output_dir / 'msa_summary.json'}", + f"--mmseqs_binary_path={binary}", + f"--mmseqs_temp_dir={self.output_dir / 'mmseqs_tmp'}", + f"--mmseqs_use_gpu={'true' if _has_nvidia_gpu() else 'false'}", + "--mmseqs_threads=8", + # One shard for all three chains, as the workflow would batch them. + "--mmseqs_batch_max_sequences=8", + "--mmseqs_batch_max_residues=100000", + *( + argument + for name, identifier in LOCAL_MMSEQS_DATABASE_IDS.items() + for argument in ( + f"--mmseqs_{name}_database_path={MMSEQS_DATABASE_DIR / f'{name}_gpu'}", + f"--mmseqs_{name}_database_id={identifier}", + ) + ), + ], + ) + self._run_step( + "Local AlphaFold 2 finalization", + [ + str(scripts / "finalize_batch_features.py"), + *shared, + "--data_pipeline=alphafold2", + f"--msa_input_dir={msa_dir}", + f"--output_dir={local_dir}", + "--template_seqres_database_id=pdb-seqres-cluster-check", + "--template_mmcif_database_id=pdb-mmcif-cluster-check", + ], + ) + + from alphapulldown.scripts.compare_msa_backends import ( + compare_af2_directories, + summarize_af2, + ) + + # Raises on a missing artifact or a sequence mismatch between the two sides. + rows = compare_af2_directories(remote_dir, local_dir) + # The measured numbers, for the job log: the assertions below are loose. + print( + json.dumps( + {"summary": summarize_af2(rows), "rows": rows}, indent=1, default=str + ) + ) + by_name = {row["name"]: row for row in rows} + self.assertEqual(set(by_name), {*self.FAMILY_CHAINS, "orphan"}) + + low, high = self.RATIO_BAND + for name in self.FAMILY_CHAINS: + remote = by_name[name]["reference"] + local = by_name[name]["candidate"] + with self.subTest(chain=name): + remote_depth = remote["unpaired"]["depth"] + local_depth = local["unpaired"]["depth"] + self.assertGreaterEqual(min(remote_depth, local_depth), 100) + self.assertBetween(local_depth / remote_depth, low, high) + self.assertBetween( + local["unpaired_neff"] / remote["unpaired_neff"], low, high + ) + # An all-zero deletion matrix is the defect the two-pass format fixed. + self.assertGreater(local["rows_with_insertions"], 0) + self.assertGreater(remote["rows_with_insertions"], 0) + # Local pairing comes from its own UniProt search, which carries species. + self.assertGreaterEqual(local["paired_species"], 5) + self.assertGreaterEqual(by_name["P61626"]["candidate"]["template_count"], 1) + # Neither backend may invent a family for a sequence that has none. + for side in ("reference", "candidate"): + with self.subTest(orphan=side): + self.assertLessEqual(by_name["orphan"][side]["unpaired"]["depth"], 20) + + if __name__ == "__main__": absltest.main() diff --git a/test/integration/test_create_individual_features.py b/test/integration/test_create_individual_features.py index e8d979b1..caba7971 100644 --- a/test/integration/test_create_individual_features.py +++ b/test/integration/test_create_individual_features.py @@ -1369,8 +1369,8 @@ def test_create_pipeline_af2_uses_hhsearch_template_stack(tmp_flags): create_features.FLAGS.kalign_binary_path = "/bin/kalign" create_features.FLAGS.obsolete_pdbs_path = "/db/obsolete.dat" - with patch.object(create_features.hhsearch, "HHSearch", return_value="searcher") as mock_searcher, \ - patch.object(create_features.templates, "HhsearchHitFeaturizer", return_value="featurizer") as mock_featurizer, \ + with patch("alphafold.data.tools.hhsearch.HHSearch", return_value="searcher") as mock_searcher, \ + patch("alphafold.data.templates.HhsearchHitFeaturizer", return_value="featurizer") as mock_featurizer, \ patch.object(create_features, "AF2DataPipeline", return_value="pipeline") as mock_pipeline: pipeline = create_features.create_pipeline_af2() @@ -1402,8 +1402,8 @@ def test_create_pipeline_af2_uses_hmmsearch_template_stack(tmp_flags): create_features.FLAGS.kalign_binary_path = "/bin/kalign" create_features.FLAGS.obsolete_pdbs_path = "/db/obsolete.dat" - with patch.object(create_features.hmmsearch, "Hmmsearch", return_value="searcher") as mock_searcher, \ - patch.object(create_features.templates, "HmmsearchHitFeaturizer", return_value="featurizer") as mock_featurizer, \ + with patch("alphafold.data.tools.hmmsearch.Hmmsearch", return_value="searcher") as mock_searcher, \ + patch("alphafold.data.templates.HmmsearchHitFeaturizer", return_value="featurizer") as mock_featurizer, \ patch.object(create_features, "AF2DataPipeline", return_value="pipeline") as mock_pipeline: pipeline = create_features.create_pipeline_af2() @@ -1437,8 +1437,8 @@ def test_create_pipeline_af2_skip_msa_returns_template_only_pipeline(tmp_flags): create_features.FLAGS.kalign_binary_path = "/bin/kalign" create_features.FLAGS.obsolete_pdbs_path = "/db/obsolete.dat" - with patch.object(create_features.hmmsearch, "Hmmsearch", return_value="searcher") as mock_searcher, \ - patch.object(create_features.templates, "HmmsearchHitFeaturizer", return_value="featurizer") as mock_featurizer, \ + with patch("alphafold.data.tools.hmmsearch.Hmmsearch", return_value="searcher") as mock_searcher, \ + patch("alphafold.data.templates.HmmsearchHitFeaturizer", return_value="featurizer") as mock_featurizer, \ patch.object(create_features, "AF2DataPipeline") as mock_pipeline: pipeline = create_features.create_pipeline_af2() diff --git a/test/integration/test_mmseqs2_af2.py b/test/integration/test_mmseqs2_af2.py new file mode 100644 index 00000000..b93b9dfa --- /dev/null +++ b/test/integration/test_mmseqs2_af2.py @@ -0,0 +1,210 @@ +"""Local MMseqs2 to AlphaFold 2 features, end to end, with nothing faked. + +A real MMseqs2 search over a small UniProt-headed database, through the real +``create_batch_msas.py``; then the real ``finalize_batch_features.py +--data_pipeline=alphafold2``, running real hmmsearch against a PDB seqres whose +entry is backed by a real mmCIF (3L4Q, influenza NS1 bound to p85beta). The +pickle it publishes is then loaded and checked for what the two stages exist to +deliver: a real template, recovered insertions, and parseable species. + +Opt-in: needs MMSEQS_INTEGRATION_BINARY and the AlphaFold 2 template tools. +""" + +from __future__ import annotations + +import os +from pathlib import Path +import pickle +import random +import shutil +import subprocess +import sys + +import pytest + +pytestmark = [pytest.mark.integration, pytest.mark.external_tools] + +pytest.importorskip("alphafold.data.pipeline", reason="needs AlphaFold 2") + +TEMPLATES = Path(__file__).resolve().parents[1] / "test_data" / "templates" + +# 3L4Q chain A without its His tag: the NS1 effector domain. +NS1 = ( + "SDEALKMTMASVPASRYLTDMTLEEMSRDWSMLIPKQKVAGPLCIRMDQAIMDKNIILKANFSVIFDRLETLIL" + "LRAFTEEGAIVGEISPLPSLPGHTAEDVKNAVGVLIGGLEWNDNTVRVSETLQRFAWRSSNENGRPPLTPKQ" + "KREMAGTIRSEV" +) +NS1_WITH_TAG = "HHHHHH" + NS1 +P85B = ( + "YQQDQIVKEDSVEAVGAQLKVYHQQYQDKSREYDQLYEEYTRTSQELQMKRTAIEAFNETIKIFEEQGQTQEKSS" + "KEYLERFRREGNEKEMQRILLNSERLKSRIAEIHESRTKLEQELRAQASDNREIDKRMNSLKPDLMQLRKIRDQ" + "YLVWLTQKGARQKKINEWLGI" +) +SPECIES = ("HUMAN", "MOUSE", "CHICK", "PIG", "BOVIN", "RAT") + + +def _mutated(sequence: str, count: int, seed: int) -> str: + rng = random.Random(seed) + residues = list(sequence) + for position in rng.sample(range(len(residues)), count): + residues[position] = "W" if residues[position] != "W" else "F" + return "".join(residues) + + +# The query is an NS1 HOMOLOG, about 90% identical, not NS1 itself. AlphaFold 2 +# rightly discards a template identical to its query -- a DuplicateError it drops +# without so much as a warning -- so a query copied from 3L4Q would find no +# template at all, and that is not the case features exist for. +QUERY = _mutated(NS1, 16, seed=11) + + +def _tool(name: str) -> str: + path = shutil.which(name) or str(Path(sys.executable).parent / name) + if not Path(path).exists(): + pytest.skip(f"{name} is not installed") + return path + + +def _run(*command, env=None): + completed = subprocess.run( + [str(part) for part in command], + capture_output=True, + text=True, + env=env, + timeout=600, + ) + if completed.returncode: + raise AssertionError( + f"{command[0]} failed ({completed.returncode}):\n" + f"{completed.stdout[-3000:]}\n{completed.stderr[-3000:]}" + ) + return completed + + +def _homologs() -> str: + """Query homologs under UniProt headers: substitutions, and one insertion.""" + rng = random.Random(3) + residues = "ACDEFGHIKLMNPQRSTVWY" + records = [] + for index, species in enumerate(SPECIES): + sequence = list(QUERY) + for _ in range(8): + position = rng.randrange(len(sequence)) + sequence[position] = rng.choice(residues) + if index == 0: + # Well inside the domain, so the alignment has to open an insertion. + sequence[60:60] = list("WWWWW") + accession = f"P{index:05d}" + records.append( + f">sp|{accession}|NS1_{species} Non-structural protein 1 " + f"OS=Influenza OX={1000 + index}\n{''.join(sequence)}\n" + ) + return "".join(records) + + +@pytest.fixture +def mmseqs_binary() -> Path: + configured = os.environ.get("MMSEQS_INTEGRATION_BINARY") + if not configured: + pytest.skip("set MMSEQS_INTEGRATION_BINARY to run against real MMseqs2") + binary = Path(configured) + if not binary.is_file(): + pytest.fail(f"MMSEQS_INTEGRATION_BINARY does not exist: {binary}") + return binary + + +def test_local_mmseqs2_to_alphafold2_features_end_to_end(tmp_path, mmseqs_binary): + hmmsearch, hmmbuild, kalign = (_tool(n) for n in ("hmmsearch", "hmmbuild", "kalign")) + env = {**os.environ, "OPENBLAS_NUM_THREADS": "1", "OMP_NUM_THREADS": "1"} + + # A padded MMseqs2 database standing in for all four protein databases. + target_fasta = tmp_path / "homologs.fasta" + target_fasta.write_text(_homologs(), encoding="utf-8") + target_db, padded_db = tmp_path / "homologs", tmp_path / "homologs_gpu" + _run(mmseqs_binary, "createdb", target_fasta, target_db, "--threads", "1") + _run(mmseqs_binary, "makepaddedseqdb", target_db, padded_db, "--threads", "1") + + # A PDB seqres whose NS1 entry is backed by the real 3L4Q mmCIF. + template_root = tmp_path / "pdb" + mmcif_dir = template_root / "mmcif_files" + mmcif_dir.mkdir(parents=True) + shutil.copy(TEMPLATES / "3L4Q.cif", mmcif_dir / "3l4q.cif") + seqres = template_root / "pdb_seqres.txt" + seqres.write_text( + f">3l4q_A mol:protein length:{len(NS1_WITH_TAG)} NS1\n{NS1_WITH_TAG}\n" + f">3l4q_C mol:protein length:{len(P85B)} P85B\n{P85B}\n", + encoding="utf-8", + ) + obsolete = template_root / "obsolete.dat" + obsolete.write_text("", encoding="utf-8") + + query_fasta = tmp_path / "ns1.fasta" + query_fasta.write_text(f">ns1\n{QUERY}\n", encoding="utf-8") + msa_dir = tmp_path / "msas" + database_flags = [ + flag + for name in ("uniref90", "mgnify", "small_bfd", "uniprot") + for flag in ( + f"--mmseqs_{name}_database_path={padded_db}", + f"--mmseqs_{name}_database_id=homologs-v1", + ) + ] + + _run( + sys.executable, "-m", "alphapulldown.scripts.create_batch_msas", + f"--fasta_paths={query_fasta}", + f"--msa_output_dir={msa_dir}", + f"--summary_path={tmp_path / 'summary.json'}", + f"--mmseqs_binary_path={mmseqs_binary}", + f"--mmseqs_temp_dir={tmp_path / 'work'}", + "--mmseqs_batch_max_sequences=4", + "--mmseqs_batch_max_residues=10000", + "--mmseqs_threads=2", + f"--mmseqs_use_gpu={'true' if os.environ.get('MMSEQS_INTEGRATION_GPU') == '1' else 'false'}", + *database_flags, + env=env, + ) + assert (msa_dir / "ns1_mmseqs_msa.json").exists() + + features_dir = tmp_path / "features" + _run( + sys.executable, "-m", "alphapulldown.scripts.finalize_batch_features", + "--data_pipeline=alphafold2", + f"--fasta_paths={query_fasta}", + f"--msa_input_dir={msa_dir}", + f"--output_dir={features_dir}", + f"--data_dir={tmp_path}", + "--max_template_date=2050-01-01", + "--template_seqres_database_id=seqres-3l4q", + "--template_mmcif_database_id=mmcif-3l4q", + f"--pdb_seqres_database_path={seqres}", + f"--template_mmcif_dir={mmcif_dir}", + f"--obsolete_pdbs_path={obsolete}", + f"--hmmsearch_binary_path={hmmsearch}", + f"--hmmbuild_binary_path={hmmbuild}", + f"--kalign_binary_path={kalign}", + env=env, + ) + + with open(features_dir / "ns1.pkl", "rb") as handle: + monomer = pickle.load(handle) + features = monomer.feature_dict + + assert type(monomer).__module__ == "alphapulldown.objects" + assert monomer.sequence == QUERY + + # A real template, found by real hmmsearch from the uniref90 profile. + assert b"3l4q_A" in list(features["template_domain_names"]) + assert features["template_aatype"].shape[1] == len(QUERY) + + # The inserted homolog's five residues reach the deletion matrix. + assert features["deletion_matrix_int"].sum() >= 5 + + # Species parsed from the UniProt headers, for pairing. + species = {value.decode() for value in features["msa_species_identifiers_all_seq"]} + assert set(SPECIES) <= species + + # Provenance records what built it, and not the tools that did not run. + metadata = next(features_dir.glob("ns1_feature_metadata_*.json")).read_text() + assert "jackhmmer" not in metadata and "hhblits" not in metadata + assert '"msa_backend": "mmseqs2-gpu"' in metadata diff --git a/test/integration/test_mmseqs2_af2_edge_cases.py b/test/integration/test_mmseqs2_af2_edge_cases.py new file mode 100644 index 00000000..c4b13d6d --- /dev/null +++ b/test/integration/test_mmseqs2_af2_edge_cases.py @@ -0,0 +1,288 @@ +"""Edge cases for local MMseqs2 AlphaFold 2 features, end to end, nothing faked. + +Four separate MMseqs2 databases stand in for UniRef90, MGnify, small BFD and +UniProt, so every stage and every cap is exercised on its own database. One real +pass through ``create_batch_msas.py`` and ``finalize_batch_features.py +--data_pipeline=alphafold2`` covers all the cases at once, as a workflow shard +would; each test then checks one case's pickle. + +The cases are the ones that fail silently when wrong: a cap that never bites, an +orphan chain whose empty alignment breaks a later stage, a template search that +finds nothing, residues the pipeline does not know, headers with no species. + +``build_edge_case_features`` is importable, so the same features can be written +somewhere durable and folded on a GPU. + +Opt-in: needs MMSEQS_INTEGRATION_BINARY and the AlphaFold 2 template tools. +""" + +from __future__ import annotations + +import os +from pathlib import Path +import pickle +import random +import shutil +import subprocess +import sys + +import numpy as np +import pytest + +pytestmark = [pytest.mark.integration, pytest.mark.external_tools] + +TEMPLATES = Path(__file__).resolve().parents[1] / "test_data" / "templates" +RESIDUES = "ACDEFGHIKLMNPQRSTVWY" + +# 3L4Q chain A, NS1 effector domain, His tag removed. +NS1 = ( + "SDEALKMTMASVPASRYLTDMTLEEMSRDWSMLIPKQKVAGPLCIRMDQAIMDKNIILKANFSVIFDRLETLIL" + "LRAFTEEGAIVGEISPLPSLPGHTAEDVKNAVGVLIGGLEWNDNTVRVSETLQRFAWRSSNENGRPPLTPKQ" + "KREMAGTIRSEV" +) +MGNIFY_HITS = 600 # past AlphaFold 2's 501 cap, which counts the query +AF2_MGNIFY_CAP = 501 +SPECIES = ("HUMAN", "MOUSE", "RAT", "BOVIN", "PIG", "CHICK", "DANRE", "XENLA") + + +def _random_protein(rng: random.Random, length: int) -> str: + return "".join(rng.choice(RESIDUES) for _ in range(length)) + + +def _homolog(rng: random.Random, sequence: str, fraction: float = 0.15) -> str: + """About 85% identical: found easily, never mistaken for the query itself.""" + residues = list(sequence) + for position in rng.sample(range(len(residues)), max(1, int(len(residues) * fraction))): + residues[position] = rng.choice(RESIDUES.replace(residues[position], "")) + return "".join(residues) + + +def _mutated(sequence: str, count: int, seed: int) -> str: + rng = random.Random(seed) + residues = list(sequence) + for position in rng.sample(range(len(residues)), count): + residues[position] = "W" if residues[position] != "W" else "F" + return "".join(residues) + + +def _cases(): + """Query sequences, each unrelated to the others, and where their hits live.""" + rng = random.Random(20260911) + deep = _random_protein(rng, 120) + x_query = list(_random_protein(rng, 110)) + for position in (10, 55, 90): + x_query[position] = "X" + return { + "deep": deep, + "deep_copy": deep, # same sequence, second name + "shallow": _random_protein(rng, 100), + "orphan": _random_protein(rng, 90), + "notemplate": _random_protein(rng, 130), + "templated": _mutated(NS1, 16, seed=11), # NS1 homolog: 3L4Q is a template + "xresidues": "".join(x_query), + "nospecies": _random_protein(rng, 115), + "peptide": _random_protein(rng, 20), + } + + +def _databases(cases): + """FASTA text per database: which hits each case gets, and where.""" + rng = random.Random(7) + uniref90, mgnify, small_bfd, uniprot = [], [], [], [] + + def uniref(name, sequence, count): + for index in range(count): + uniref90.append((f"UniRef90_U{name}{index:04d} {name} homolog", + _homolog(rng, sequence))) + + def uniprot_hits(name, sequence, count, *, with_species=True): + for index in range(count): + accession = f"Q{abs(hash((name, index))) % 10**5:05d}" + header = ( + f"sp|{accession}|{name.upper()[:5]}_{SPECIES[index % len(SPECIES)]} " + f"{name} OS=Organism OX={9000 + index}" + if with_species + # A UniParc-style header: no species anywhere in it. + else f"UPI{index:010d} {name} unassigned" + ) + uniprot.append((header, _homolog(rng, sequence))) + + uniref("deep", cases["deep"], 30) + for index in range(MGNIFY_HITS): + mgnify.append((f"MGYP{index:012d}", _homolog(rng, cases["deep"]))) + for index in range(20): + small_bfd.append((f"BFD_deep_{index:04d}", _homolog(rng, cases["deep"]))) + uniprot_hits("deep", cases["deep"], 8) + + uniref("shallow", cases["shallow"], 1) + uniref("notemplate", cases["notemplate"], 12) + uniprot_hits("notemplate", cases["notemplate"], 4) + uniref("templated", cases["templated"], 12) + uniprot_hits("templated", cases["templated"], 6) + uniref("xresidues", cases["xresidues"], 10) + uniprot_hits("xresidues", cases["xresidues"], 3) + uniref("nospecies", cases["nospecies"], 6) + uniprot_hits("nospecies", cases["nospecies"], 5, with_species=False) + uniref("peptide", cases["peptide"], 3) + # "orphan" gets nothing, anywhere. + return {"uniref90": uniref90, "mgnify": mgnify, "small_bfd": small_bfd, + "uniprot": uniprot} + + +def _run(*command, env=None): + completed = subprocess.run( + [str(part) for part in command], capture_output=True, text=True, env=env, + timeout=1200, + ) + if completed.returncode: + raise AssertionError( + f"{command[:4]} failed ({completed.returncode}):\n" + f"{completed.stdout[-3000:]}\n{completed.stderr[-4000:]}" + ) + return completed + + +def build_edge_case_features(workdir: Path, mmseqs: Path, *, tools: dict, python=None, + use_gpu: bool = False) -> dict[str, Path]: + """Build every case's AlphaFold 2 pickle through the real CLIs; return the paths.""" + python = python or sys.executable + env = {**os.environ, "OPENBLAS_NUM_THREADS": "1", "OMP_NUM_THREADS": "1"} + cases = _cases() + workdir.mkdir(parents=True, exist_ok=True) + + database_flags = [] + for name, records in _databases(cases).items(): + fasta = workdir / f"{name}.fasta" + fasta.write_text("".join(f">{h}\n{s}\n" for h, s in records), encoding="utf-8") + plain, padded = workdir / f"{name}_db", workdir / f"{name}_gpu" + _run(mmseqs, "createdb", fasta, plain, "--threads", "2") + _run(mmseqs, "makepaddedseqdb", plain, padded, "--threads", "2") + database_flags += [f"--mmseqs_{name}_database_path={padded}", + f"--mmseqs_{name}_database_id={name}-edge-v1", + # High enough that AlphaFold 2's own cap is what bites. + f"--mmseqs_{name}_max_sequences=2000"] + + template_root = workdir / "pdb" + mmcif_dir = template_root / "mmcif_files" + mmcif_dir.mkdir(parents=True, exist_ok=True) + shutil.copy(TEMPLATES / "3L4Q.cif", mmcif_dir / "3l4q.cif") + seqres = template_root / "pdb_seqres.txt" + seqres.write_text(f">3l4q_A mol:protein length:{len(NS1) + 6} NS1\nHHHHHH{NS1}\n", + encoding="utf-8") + (template_root / "obsolete.dat").write_text("", encoding="utf-8") + + queries = workdir / "queries.fasta" + queries.write_text("".join(f">{n}\n{s}\n" for n, s in cases.items()), encoding="utf-8") + msa_dir, features_dir = workdir / "msas", workdir / "features" + + _run(python, "-m", "alphapulldown.scripts.create_batch_msas", + f"--fasta_paths={queries}", f"--msa_output_dir={msa_dir}", + f"--summary_path={workdir / 'summary.json'}", + f"--mmseqs_binary_path={mmseqs}", f"--mmseqs_temp_dir={workdir / 'work'}", + "--mmseqs_batch_max_sequences=32", "--mmseqs_batch_max_residues=100000", + "--mmseqs_threads=2", f"--mmseqs_use_gpu={'true' if use_gpu else 'false'}", + *database_flags, env=env) + _run(python, "-m", "alphapulldown.scripts.finalize_batch_features", + "--data_pipeline=alphafold2", f"--fasta_paths={queries}", + f"--msa_input_dir={msa_dir}", f"--output_dir={features_dir}", + f"--data_dir={workdir}", "--max_template_date=2050-01-01", + "--template_seqres_database_id=seqres-edge", "--template_mmcif_database_id=mmcif-edge", + f"--pdb_seqres_database_path={seqres}", f"--template_mmcif_dir={mmcif_dir}", + f"--obsolete_pdbs_path={template_root / 'obsolete.dat'}", + f"--hmmsearch_binary_path={tools['hmmsearch']}", + f"--hmmbuild_binary_path={tools['hmmbuild']}", + f"--kalign_binary_path={tools['kalign']}", env=env) + return {name: features_dir / f"{name}.pkl" for name in cases} + + +def _tool(name: str) -> str: + path = shutil.which(name) or str(Path(sys.executable).parent / name) + if not Path(path).exists(): + pytest.skip(f"{name} is not installed") + return path + + +@pytest.fixture(scope="module") +def features(tmp_path_factory): + pytest.importorskip("alphafold.data.pipeline", reason="needs AlphaFold 2") + configured = os.environ.get("MMSEQS_INTEGRATION_BINARY") + if not configured: + pytest.skip("set MMSEQS_INTEGRATION_BINARY to run against real MMseqs2") + tools = {name: _tool(name) for name in ("hmmsearch", "hmmbuild", "kalign")} + paths = build_edge_case_features( + tmp_path_factory.mktemp("edge"), Path(configured), tools=tools, + use_gpu=os.environ.get("MMSEQS_INTEGRATION_GPU") == "1", + ) + loaded = {} + for name, path in paths.items(): + with open(path, "rb") as handle: + loaded[name] = pickle.load(handle) + return loaded + + +def _msa_rows(monomer) -> int: + return int(monomer.feature_dict["msa"].shape[0]) + + +def test_deep_alignment_hits_alphafold2s_mgnify_cap(features): + """600 MGnify hits were found; AlphaFold 2 keeps 501 counting the query.""" + deep = features["deep"].feature_dict + rows = _msa_rows(features["deep"]) + # query + 30 uniref90 + 20 BFD + 500 MGnify, all distinct by construction. + assert rows == 1 + 30 + 20 + (AF2_MGNIFY_CAP - 1), rows + assert deep["num_alignments"][0] == rows + + +def test_the_same_sequence_under_two_names_gets_two_identical_pickles(features): + np.testing.assert_array_equal(features["deep"].feature_dict["msa"], + features["deep_copy"].feature_dict["msa"]) + assert features["deep_copy"].description == "deep_copy" + + +def test_a_shallow_alignment_is_kept_as_it_is(features): + assert _msa_rows(features["shallow"]) == 2 + + +def test_an_orphan_chain_gets_query_only_features(features): + orphan = features["orphan"].feature_dict + assert orphan["msa"].shape[0] == 1 + assert orphan["msa_all_seq"].shape[0] == 1 + assert orphan["deletion_matrix_int"].sum() == 0 + + +def test_no_template_gives_alphafold2s_empty_template(features): + templates = features["notemplate"].feature_dict + assert list(templates["template_domain_names"]) == [b""] + assert templates["template_aatype"].shape == (1, len(features["notemplate"].sequence), 22) + assert not templates["template_all_atom_masks"].any() + + +def test_a_homolog_of_a_known_structure_finds_its_template(features): + assert b"3l4q_A" in list(features["templated"].feature_dict["template_domain_names"]) + + +def test_unknown_residues_survive_as_alphafold2s_unknown(features): + monomer = features["xresidues"] + aatype = monomer.feature_dict["aatype"].argmax(axis=1) + unknown = 20 # residue_constants.restype_order_with_x["X"] + assert [int(aatype[i]) for i in (10, 55, 90)] == [unknown] * 3 + assert _msa_rows(monomer) > 1 + + +def test_pairing_rows_without_species_are_kept_but_unlabelled(features): + """No species in a UniProt header means no pairing -- not a failure, and not + a UniProt lookup to recover one.""" + all_seq = features["nospecies"].feature_dict + assert all_seq["msa_all_seq"].shape[0] == 1 + 5 + assert set(all_seq["msa_species_identifiers_all_seq"]) == {b""} + + +def test_a_short_peptide_is_featurised(features): + peptide = features["peptide"] + assert peptide.feature_dict["aatype"].shape[0] == 20 + assert _msa_rows(peptide) >= 1 + + +def test_every_case_carries_the_same_feature_keys(features): + keys = {name: frozenset(m.feature_dict) for name, m in features.items()} + assert len(set(keys.values())) == 1, keys diff --git a/test/integration/test_mmseqs2_command_contract.py b/test/integration/test_mmseqs2_command_contract.py index 2313267d..2bf641be 100644 --- a/test/integration/test_mmseqs2_command_contract.py +++ b/test/integration/test_mmseqs2_command_contract.py @@ -11,14 +11,12 @@ pytestmark = [pytest.mark.integration, pytest.mark.external_tools] -try: - from alphafold3.cpp import msa_conversion as _msa_conversion # noqa: F401 -except ImportError as exc: - pytest.skip( - f"AlphaFold 3 MSA conversion is unavailable: {exc}", allow_module_level=True - ) - -from alphapulldown.feature_batch import ( # noqa: E402 +# No AlphaFold 3 skip here any more. This module exercises the shared protein +# search, which the AlphaFold 2 image has to run too -- and that image has no +# AlphaFold 3 at all. Skipping the whole module on its absence meant an AlphaFold 2 +# environment reported success while silently skipping the one test that runs a +# real MMseqs2 search end to end. +from alphapulldown.feature_batch import ( DatabaseSpec, FeatureRequest, MsaBatch, @@ -47,9 +45,15 @@ def test_real_createdb_padded_search_result2msa_and_unpack_contract(tmp_path): query_sequence = "MKTAYIAKQRQISFVKSHFSRQDILDLWIYHTQGYFPQYQKVEKLLKQGADVVVT" target_sequence = query_sequence[:-1] + "A" + # A UniProt-headed hit with a four-residue insertion. result2msa mode 2 keeps + # this header and drops the insertion; mode 5 keeps the insertion and cuts the + # header to "P0CTR1". The bundle has to carry both, on the same row. + inserted_sequence = query_sequence[:20] + "WWWW" + query_sequence[20:] target_fasta = tmp_path / "target.fasta" target_fasta.write_text( - f">target_hit expected description OX=9606\n{target_sequence}\n", + f">target_hit expected description OX=9606\n{target_sequence}\n" + f">sp|P0CTR1|INSRT_HUMAN inserted OS=Homo sapiens OX=9606\n" + f"{inserted_sequence}\n", encoding="utf-8", ) target_db = tmp_path / "target" @@ -87,9 +91,40 @@ def test_real_createdb_padded_search_result2msa_and_unpack_contract(tmp_path): "gpu" if use_gpu else "cpu" ) + # The point of the two-pass format, against the real binary: the species + # header and the insertion arrive together, on one row, in the paired MSA + # AlphaFold pairs chains from. + paired = payload["pairedMsa"].splitlines() + header_index = next( + index for index, line in enumerate(paired) if line.startswith(">sp|P0CTR1|") + ) + assert paired[header_index] == ( + ">sp|P0CTR1|INSRT_HUMAN inserted OS=Homo sapiens OX=9606" + ) + assert "wwww" in paired[header_index + 1], paired[header_index + 1] + assert ( + paired[header_index + 1].replace("wwww", "").upper() == query_sequence + ), "removing the insertion must leave the row aligned to the query" + + # And the bundle says which database contributed which unpaired rows. + assert [span["name"] for span in payload["unpairedDatabaseRows"]] == [ + "uniref90", + "mgnify", + "small_bfd", + ] + assert ( + sum(span["rows"] for span in payload["unpairedDatabaseRows"]) + == payload["unpairedDepth"] - 1 + ) + + +@pytest.mark.parametrize("num_iterations", (1, 3)) +def test_real_nucleotide_createdb_search_and_unpack_contract(tmp_path, num_iterations): + """The same contract for RNA: a nucleotide database, searched on CPU. -def test_real_nucleotide_createdb_search_and_unpack_contract(tmp_path): - """The same contract for RNA: a nucleotide database, searched on CPU.""" + Also with the protein-only iterative search raised, which must not reach the + nucleotide search: there the pinned build exits 1. + """ configured_binary = os.environ.get("MMSEQS_INTEGRATION_BINARY") if not configured_binary: pytest.skip("set MMSEQS_INTEGRATION_BINARY to run the real command contract") @@ -127,6 +162,7 @@ def test_real_nucleotide_createdb_search_and_unpack_contract(tmp_path): max_residues_per_batch=1_000, threads=2, rna_databases=databases, + num_iterations=num_iterations, ) result = MsaBatch( diff --git a/test/test_data/fastas/O31718.fasta b/test/test_data/fastas/O31718.fasta new file mode 100644 index 00000000..435bfcab --- /dev/null +++ b/test/test_data/fastas/O31718.fasta @@ -0,0 +1,2 @@ +>O31718 +MIYKVFYQEKADEVPVREKTDSLYIEGVSERDVRTKLKEKKFNIEFITPVDGAFLEYEQQSENFKVLEL diff --git a/test/unit/data/small_bfd.mode2.txt b/test/unit/data/small_bfd.mode2.txt new file mode 100644 index 00000000..9369aaa2 --- /dev/null +++ b/test/unit/data/small_bfd.mode2.txt @@ -0,0 +1,240 @@ +>O31912 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A163VT74_9BACL +-----------IDPAKWGISTDGTNSRATTDGLNAALADAKSKGFGEVYLPKGKYLIDAVCKTN-HSPEIGGGIRVPSNLKLTLDSEAELKVEPNGSYGYSCIFLDNVHNVTITGGIVTGDRNEHDYS--NKTKPTHEWGFGINVRGGTNITIDNVRIKDCSGDCIYVNAIGMINYGTVPYTPPQKVMIQNCTLDGSRRNNISISACDGVVIRNNLILNAGIQTIGPGFGIDIEGYGEGDIDYETPLNIVIQGNQFRGNRVYSVGNFNGYGVVIEGNFADNTLSYGNGTDTVIANNVLIRT-DRQRTGIDGQGVSQGLEANHVTIMGNIVKGFGSGMDIRGKDVVVTGNALSHEAGVGIAAFAAENVWIANNSVHRTKGTPYRIASCKDVQLVNNKAHGSDKT-AIEANASSQVILRGNVVRDCSGGIEASNSEVVHIDLTEY--KGKAYAISFDSKSEVTLKGNRIPGPRNTAIYGEGGIKRAKIADNEIADANSFTAIQIVGGAKHEIVGNNVTFNKSSNGGVGIYLKDAKDSIVAKNTVYSNSEYALTHSIATKESTGTKVLNN------------------- +>A0A090ZKM7_PAEMA +---------YVIDPAQWGIKTDGTEAVKTTEGLNKAIAHAKSAGYNEAFIPKGTYLIQGVGTTFPNTPEKGGGIVVPSHMKLTLDHEAELKVQPNAERGYSCIYLRKVQNVTISGGIITGDLDQHDFSKL--PKSTYEWGFGIYVHGGKNITIENMKIRKCIGDCIFLGSVGLLGVDPDYDKPEK-VAIRNCSLDGARRNNISITAADGVFVENNVITNAG--TVKPWAGIDIEGYGEGAIDYEEPRRVVVRGNVFRGNAEVSVLNFNGYGVIIEGNHADNTFSYGNGTDTVISNNVMVRTDGSK-VAIAAQQVSNGYDGNNVTIVGNIIKGFSSGIDARGKDVVVTGNTVSNTGGTGIGVWDAENVLVADNAVHRCAGLPYKVDNSNDVQFLNNKAL-HSERFGLELDKSTNVVLRGNSFGQCNGGIWGTKGTSVFAEGNYISYTGKNYAISFDKNSDVTLKENYIFGSRSVAIYGESSAGKIKIADNEISDITGNSAIQIKGGQRAEIVGNRITFKRKDDAAYGISLDNAEDAIIAQNTIYSNNGKSIPNAIVTESSKRTKVLNNLLINGKMLLNKDDTNI--- +>C2WEL3_BACCE +---------YLIELSRWGI--INDGSKETEKEINNALQWAYDNGINRCILSSGTYLINAVGPPNDLQ---AGGIKIPDNMTLDLWHDTVLKVKANDSYSYSCIYLYNKNNIKIRGGTIQGDRYHHDFSTAPTGKLTHEWGRGINIIGCSNITIDNMNIKECTGDAIDVLSIGLMN--TQVYIPSSNITIRNCTLDKSRRNNLSLEGCDGVLVENNVITNAGDDGTAPRFGIDIEGYGEGATDYVVPLNIVIKNNKFEGNVTTSICNFNGYNVIIEGNISDNTISYAYGTQTIIS-NNIFKRVDLTTKAISSIGTAQGLDFNNTTITGNIITGFDTALDIRGKNVTVSSNIIYDVK-IGISLFQAESILVQGNLIKKATFGKIIINTCTNIKCTENQLK-DIGMLCIELNNSSAVTINQNDIFNSKQGIRISKSNAVSIDLNTF--NSPSYNIDFDATSNVLIINNLLKNCSSFAINGSASSKS-RIIKNIIENFTAISAINLSGG-RHELIDNILIANKNIAGGYGINLHSCNQSTVLRNHIFSSSIYNLSTPIKTNTSTNTKIIEN------------------- +>A0A238U6X6_9FLAO +-------------------------------------------------------------------------ILLPSNFHLSLHEETVFRVQPNAFPWYSLMTIDKKENVKISGGNFIGDRYEHDYPFFDLKRSTHEWGVLLLVRGSENINIDNITLKSSIADGLITGSEGHRIYPETVW--NKKVSLTNSIVSDNRRNNISITDGEDILIEGNEILDAGGETVAPRFGLDVEGYDESRKTYEWVENVIIRNNIFKGNEAGSIIVYTGDNVLIDGNFSDHVIAQN-----NTSGSKIINNTEARDDVRGRIGISTSDTGN--DVKNNTIRNFFGGYNIRGNNAEVSGNTVEGATVCLL------------------------INKAENIKVHDNTTSGAIASKAIRLTDANNIEIYNEKFT-LSNGFYLE-SIDFNMPNDDFHLN-------------------------------------------------------------------------------------------------------------------------------------------- +>LauGreSBDMM110SN_4_FD.fasta_scaffold226965_1 +-------------------------------------------------------------------------IHLPSDFHFKMSKSTFLRVQPNFWPRGVLLSVYEQKNTLVSGGNLIGDRYTHNYAPIKDERDTHEWPVLLSIAGCKDVIFEKIYMTDSTGDAVTGATNGSRDIGGADKKFNQNVIIRGCVMNASRRNNISITDGEDIFITNCIIQNGGGDTVAPRAGIDIEGYNPDGRNFEIVKRVTISGCTFKNNRVASIIDYSGINTTIKNNTSDHGFFASFSTGTKFLYNTFKASAINKDKVAIVTGINNTQLSKNNEVTGNKIEGFRVGITTQGDEGNVSNNTI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_4058357 +-------------------------------------------------------------------------IKVPSNTHLLMSDNTFIRVQPSNNPFSRLLMTYKAQNVLIEGGNLVGDRYLHDYSEIGVSRATHGYGSLINIAGSQHVTVDNVNIYEGEGDGVLIQISAIRNKDGSIKAESSNVVIKNSLIDKCRRNNFSIIDANGVLIENNVISNAGGEGTAPEVGIDLEAYRERRSEYERVTNVTIRNNEFVGNDVADVIVYTASFVDIIGNTFDNRVGVHAGHDVKIANNEF--TAGERAVSFDNFIVNETETYN-IDVTGNTISGYDTAMKVGTQNVTVSENKIYDFVTGINITDI-ENAQISNNTLE------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1V5WUJ2_9DELT +---------YVVDTDKWNIPTDGSDPERTSAGLSEALAWAVDNGFGTVRLPAGAYVVG-----REINSMFIEGVVVPGPLRLDFEPGAIIQMKPNDHPFYCILDIADASDVWIRGGTVLGDRESHQY----VGESTHEFGTAVCVGGSERILIENMSLAEATGDGITI-----NDAPG----SSRDITIRGNDIHHHRRQGISIISGSAIVIEDNEIHHIAG--TAPQFGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A090II36_9GAMM +--LLNSSINFVFDNQRWGVIVNNEQAKENTRLFQYALNQAHNVHANVFRINKASFWVGNYKKFN--STEL-SGITLPSNIKLSMRHDTILRTQANGYARYALLGLYNADNVTIEGGVLIGDRDTHDYK--DPQSPKPYWGHLMKIGGSRNVTIKGVTFKNATADGLSIHSLGTYKRTGSIET--KNILVTDCLFDNNRRLGTAITSGSEIIVEHNTYLNSGSESVSPAWAIDIEGGYKDHEYLERPYNITIRNNIERNSYRGAFIGAIGDGITIENNNTENTIALG-SVFNSKAFNNTITRDLNKEY-LNPNGLSVAYDGEKMFYPTEEVVGIRARMYISGSGNSIFNNSISN-SLTGITIQKAKNAEIYNNSVHSNNSIGLSARDSNNVNVYDN--DFNIEGLAIRFISINE-KLGHENFS---------------MYLNNNRFTSSGY----NKAASVSRSRNVYFNENNFSNIGFI-MYNIQLIGNRV-ETKTRIGLQIEEGNEQIKLHDNLVIHPEKKK---CIRNLSEQIPDIKNNV-------------------------------------------- +>SRR5690625_80756 +---------YELELARWNVSNNGTRPHETTKGINEALNWAKENGYTSLLIPDGTYSIAKGNAENDRHAR----INMLSDMTFLMSNNTILQKEPNGFEEYSVLHVGAVKNVVIQGGTLIGDREDHNYSSGDWSSGTHEWGHGISIVGGENITVDGVKIKDFTGDGIYI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_9554453 +---------YLVELDRWGISADGTNAEATTDGINEAIRWAQGEGYGRVRLPAGTYLIG-----KRLYDHYTGGIELVDDVALMMDDETVLQIVPNDTWAYCGIAMSGVRNAGVYGGTIRGDRDEHTYG----GSMTHEDGHCICIHESELVEIDGVTMEDPTGDGVAIVAEGGDG------SSCKHITIKNSEIARGRRQGISIVGGTNVWIENNEIHHIEG--TAPQFGIDIESLNFTSR------DIVIRNNRFHHN-RGGDFENADGKVWFEENHLD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>APAga8741243855_1050100.scaffolds.fasta_scaffold124648_1 +---------YTIDNEQFGIYSNNTHARTTTDGINEALNWAKSHGYTKVRFAAGTYLIQC--TWNNRYCAPDDGILVPSGMTLDLG-TATFRMEANNYPAYTIFGIVNKSNVTITGGTLIGDLGSHTYSSV-SGSSSHEWGFGICISASKNVVIDDVTIKNMTGDGVILGSYAALSNGGRV---CSNIKVTDCTISNCRRQGISVIGADSELARNRIYGIKGTD---PQYGIDVEDYVVDDLKIHH---NNISDC-----SGGAINCNKGENYDVYSNTVDNIIA-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2G5GBI8_9FLAO +------------------------------------------------------FVIDKLDAYFKIDGPLSEGIQIPSNFTFRMSENTHLRVQPNATDKCTLLSVYLSDNAVIEGGNLYGDRDEHDYSDGIND---HGWGHLFTSRGSTNVTVRNVTMIDAAGDALKLEGEGHAVNPD--YAPTRNFLATGCKFIRSRRNNLSITAADGVVIEDCDFIDAGIHTTIPGFALDIEALKPN----ELSENIIIRNNRETGSRRGGFLVAIGDKVTFEGNVINSAINLQSARNCIVRNNIVTAQSDAKEYGAGII-TGRSDRGNLVTIYNNTVNGFSTGISISNFDMKVYGNTINNCSNVDKSAGISMGASLNNVVVRNNDVNVMRFANVNNTDESGNKGNNIVSGSSTPINSSHGIELIENTFNNAYEFYNCSNLNII------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A167HAM4_9BURK +---------------RWGVASNASNATATTDGMQAAIDWASSQGIGQFRVPAGEYLLGKIQTYN-----YAGGIKLPSNMALVLEPGAVLRMVPNDRWNYCVVTINGKKNVSVSGGTIVGDRYNHTYTPSSSGGTAHDEGHAICIEGSSQVEVQGVYITQANGDGILIV--------GKAPSTPQDITITGNNFDTNRRQGISIVGGARVLIEGNQIHHTKG--TSPQFGIDIEPLGGRGNNFHHNRGGDVVNTRTMHQGEASTTGGDDGRT-----YIDGPIVFWPEADQTIRNNNI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A1I1IH73_9FLAO +-------------------------------------------------------------------------INVPSDFHLIMTDNTHLRQQPNANKRATLLAAYLISNTIIEGGNLHGDRDTHDYSDTSTSQ---EWGHCIRVGASKNVIIKNMNIYDAGGDGIDIHAYGHAYNSHYTYTENLLITNNK--IYRSRRNGISITDGRNIVIEDNEFIDSGVSTVAPGWAIDVEAVRNSGVIFEIAEDILIKNNVERGSKYGGFIIHTGDRVTIDGNTMENSIAYAGTIGSVIKNNNLKSNSETALRGQTTGIIAQNKASSKNSVYGNTVYGYPIGIKVGDTNLNVYNN---NILECAVG---------------------ISLNTSKDSRIYGNTIKSTT---------ANSRGISNHTISNLIGSGLDENNESAKSNVIDVVIVFNGIKEIENSDTHSIIIKNNIIE--NGANLWLIDINNFEMHDNVI----------------------------------------------------------------------------------------------- +>A0A238U509_9FLAO +--LLNNSLTIQGDFDKWGIEGVTTNEISRT---NRDIL---ENNMTFIKLGASIFKIDKMDAFNVDEPDIEAAINVPSDFTLKMTNNTHLRMQPNAAIRPTLLATFTASNVTIDGGVLHGDRDSHDYTTINS---THEWGHLLRITGTKNSVFKNIRFEDATGDAIDVHAYGHSFDPH--YTYCDNVLITNNIMLRSRRNHISITDGRNITVEKNDFIDASIHTIAPGFAIDVEAV-----RHGNPRGISIAEDIFIKNNTGAVTVHTGDRVTIEGNKFENSISYSTSIGTIIRNNEIINNG----TAIVAGRADRYDDNYNGKVYGNTIENYAIGMTVSNKDLEVYANKITN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A0P0CI41_9FLAO +-----------------------------------------EGSFELVKLGVSTFIIDAMDAYFKVDDENFKGINPPSNFTLKMSENTHLRTQPTNFSNYALISVRDVENVVIDGGNLYGERDEHDYS----SGGSHEFGMCLTVSGSKDVTIKNMTITDALGDGIIIDNIG-HTYDSF-YTYTDNLLIQNNKIIRSRRNGISIVEGKNIVIDGNELVDTGITTAAPMWAIDIEPVWENGIKYQIVEYVTIKNNIERGSEKGGFINARGWYITYENNTMENTIAIGETVGSIVRNNIFKNPGKNSNVAIDPLGYGN-ERNYDNEVYGNTITGFPKGIELQDPGIDLHHNTM------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>J8DZ85_BACCE +--MIEKVNIYVIELDKWNIKKDGTDAVNTTKGINKALLWAKENDYDVCKLPAGNYLVDK-----------DSNIEMVSDMTLDLF-GCTIRKETNGYQGYSIVRIFRQKNATILGGTIEGDKDTHDYSTIP---GTHEWGIGIDVSGNRNIKIDSVKIKNTTGYGVRTGTYGHLSW---VYTTDESGTVLKADVNFTRSNQIQENGYFSIMGNGYGFTKDGGEVNLDRVPITIYFFDESNKFLGKITKRTFDNIYYSSFPKGT----SKFKIGFRFNYNNNALSMTIRSMTYTKGINVIN---TDIYGCRALGIAITGAQNMLV---DNCEIYGIGGINPGYAIDIED-----------GYNINQNIIIRNNYIHDNNNGAIVVVSARNVLLESNKFYG-----SVFLGGSRGENYLSR--HNLYGSTNAGGGDAATITFDDYMLEGQLYNAFYDNDNMTFVLQSDTF---------------------------------------------------------------------------------------------------------------------- +>X4ZGB9_9BACL +---------YLIELARWGIYNDGTHPVETVKGINNALVWARQKGITATTLPAGTYLIDKASRIN-----------MVGDMLFDLPMDAVLQKETNGKERYDVMYVGYANNVTLRGGTYLGDKLTHDYSQRDPNTGTHEGGYGIFVEGAKNTTIDGVKAMNFTGDGLVLGGFGTM---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1A5YEI2_9BACL +---------HMIDLKRWGISSNGTKPVQTTQGINKALQWAAKSKITAVTLPPGTYLIDK----NSR-------INMVGNMLFQLSDDTILKKQENGKEHYELMFIGYANNVTLRGGTYLGDKDSHDYSKKDNPHTTHERGYGITVLGANNITIEGVKGTHFTGDGLIIGAH------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2B8JB68_BACME +--------------EKWTIHNDGTYPIETTSGFNNALAWASAQGIHTFKVPAGIYLIK-----KGVDYDATARINMVSDMTFIADNKAIFQKETNGLTGYSVMYIGQVKNAIIKGGVYKGEKDTHDYSI----SSTHEWGYGVLVEGGENIIVDDIEAYNFTGDGLWVPTKGEVNIPASVYDNSKSVTVKNSKMHDNRRQGITVGGGYGVLLENNEIYNIRG--IAPQSGIDVEGYGINGNVHDNVYGVILYDGIGATVEENQIKNHSYPGLVVQEEYKDALVQNNYNSGMSIK---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1M6AGX2_9FLAO +-------------------------------------------------------------TTNQNFYPSREAINVPSDFTLRMTDNTNLRVQPNSRKNYVLLAVRDASNVRVEGGNLIGDRLEHD---DNSQPGPHAFGFVLMIHGGSNVDLVGVRTILGTGDGIDVNSIGFTFEAG--YIPSNNIRITNCIMDSNRRNNMSITDGFNIVVDGCQFLNAGIDMPGPGVAMDVEAFAGNFILYERAYDLTFRN-NFEKGSKGSFVVAIGEDVTIENNTTEDGIAIGAGHGIKIIGNTLIAAADDNGAGITTGHPNSTDTYDNV-IANNRIIGHNIGIAAYQRDMKIYGNVIE------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>GraSoiStandDraft_43_1057313.scaffolds.fasta_scaffold3393195_1 +-----------IDNAYWGIVTETNTEIANMENINRAIKTAHENGIYKIKLAKATYWFDA--TSDKTTPSIG----LLSNMQFNL-XXAXLRVMPNNLTHHYFIYIESAENVKIFNGTITGDRYEHGY--VPATYPTHEWCHGLRVGSNSSNYCKNIEIYDLVVQE--------FTGDGINVSWSKNVTIRNTEVSNARRNGITISNTDETYIYDNYIHDTHG--VSPACGIDLEKAAGDGPKNIVIRNNRIYDCINPETGQGQAMAISGGQVTVRDNDIRGVIGFAYAEKILIENNRI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A229GVH8_9GAMM +---------------------------DDTAAIQKAIDAVAAKGGGIVEIPAGTYMINGAATLGPGDVPRTSGLQVKSNVIIRMADDTVMQVIPNGEKHYDIFNIYNAENVAIMGGTLRGDRHSH---LNDQG----EWGSGIKIASAKNVVIEKVIAREFWGDAVHISDSG-----SLPRTPSQNVTIYQLAADGNRRQGISITSADKVLIEDSAFKNTGGQGTPPMAGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A098MBD8_9BACL +---------HLIELSRWGIYNDGTHPVETTKGINNALTWAYQQGITATTLTPGTYLIDKASQINM----------VP-NMLFDLTMEVVLQKETNDKESYQIVSLDYGDNVTLRGGTYIGDRLTHDYSKKDGSAGTHEFGYGIIARGVKNLVIDRVKTTHFTGDGIILAGHGTM---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2A2AT09_9BURK +-----------------------------------------------VWIPAGTYMIDTVNACGGWGQE-RCGLQMRSGVTVHMSQQAVLKAMPNGSRHYNIFHFNDVENAHVLGGQLQGERYAH---RIPTDGRLGEWGAGLVMRGARHAAIENVTAREFWGDGF--------------YVGGSSQNVKFCAVDKNRRQGMSITDVDTIVVQDSVFKNTHG--TPPQDGIDIEPWGENEPIREHVKNVTIRRSQFINNGIGMVTTHPGENVVLEGNFIDNSIGLGLSWKTRITGNRIIN----SQY--LNIGLGPLAT--FITVTDNAVTG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_2407419 +-----------------------------------AAIQAAINSLPTVTIPAGTYLIDTSKKIN-----------LKSNMLLKLDPNAILKAKSCSLIRHYLVYVNGKTNVEIAGGQLVGDRDGHNY----VGSSTHEWGHGIQILGSTKVTVRDLRVSKCTGDGVCIGG------------GASDVVIGNIIATNNRRQGLSITNCTNIKVYDSEFSYSKG--TSPECGIDIEGHSNNNGKYKRVSGVTITQCTLERN--GSLGLGTNGCSGIK--FTNNIVRYNSATGV------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1719318_174446 +---------YKLNLEDWDIPNNGHEPRKTTENLQKAIDWAHGNAYTKVLLPRGHFLLGITNGKRKEDNFSMRGLSMHSNTEFILDSAATLEMVSNDKVMYCIICIEDVTDVIIRGGTLKGDRETHTYTP-HHNRTTHEWGHGILISDRHRILVTNMEIKDVTGDGVYVKSEKK--------SIGSDIIIKNNDIHNARRQGVSIVGGLRVKIEDNEIHHIKG--TSPQFGVDIEG------PWTVTKDVIIHRNNFHDNRGGDVVNFDGKNVFITENKMIESDSYSYT---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>APHig6443718053_1056840.scaffolds.fasta_scaffold2008830_1 +-------IKYYTP-QQFGAVANDTG--DDTVAFNRALAAASSSSTDTVFVPAGTYMIKADGG--------DGGVQVLSKTKLKMDPGAVLQVITNAERGYNCVRTNGVTDAEISGGTICGDRTTHTGT-------SGEWGHGIGIYDSTDVTISNVVVKNCWGDGVYI---GTAN-DNSTTAKSRQISLSGVTTDNNRRNGLSVVAADGVTVDGCLFVNTNG--TDPQAGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_7665223 +---------------------------DVTSQLQTVLTNIAKNGGGIVYLPKGNYMIKATNPQSLLTPAKLEGLQVGSNTTILLDKDASLSVIPNNFWNYLVLNIQGADNVNILGGTLNGDRLSHDMSNPNNSPYYGEWGNGLSIQSSNNTLVSGVKFKNFWGDGISLFPDKDQAEAGAL-SQAKNVHITGCTFDYNRRQGISVGHANNVEIDHSLFENT--DGTGPAAGIDLE---PGGGSTEQVTNVKIHDNVFLNNNNAGLTAYAAPKSKV--------------SDVHVYNNTFINNG-------------AWMPG---QITFNN-----------AEYIEIDHNKFDNDD--ASRFHSSWIVNTANDNIHDN-----YGRNSSIAKEAHGEGKVTNNYVSSIMIENTGYDVANNHLPN-------------EISSTDLGTMGANWNYQNDVDYPGLATNEKVFNSRGKALNVTANPDNTVLNQSDPSNCQADISFDIDG---------------------------------------------------------------------------------- +>SRR5699024_10005537 +-------------------NAKGDGVTDDTNSINEAIDYAVENNINTVYFPSGIYMIDAEEIIPNGSK---GGIHLKSNITLKLDDNAILQAISNSAEGYNIIRAKESNNIKVIGGTIKGERSNHSGS-------EGEWGHGIHLKGCSNVYIQS-NIIDCWGDGIYVG--------GDVSTPTKNLIDENTVCDNNRRQGISIVSGKHIRLLNSDFINTNG-TL-PESGIDIE------PSHDRHIDVKVIDCNFNNNGTGFLIDGKSG--SVEDIYVNGI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5207342_2131982 +---------------------------DDTRAFQDAIDAAKGG---IVIVPAGDYLIDPLHS-----------VRVRSGTQLRMDRNARLRAIPNAAPRAYVLLLQGVEDITISGGQILGDRKEH----LGT---TGEWGHGIAIYGASNVKVRDVRISGCWGDGISIGS--TKAGKGGVMRPSTDIEIANVASLGNRRQGLSIGRSRRVYVHDCEFSDTGG--TPPSAGIDVE--PDAG---DIAQDVRIERCILRRNGPGRATSVAIRDCTIEDNRNAGVLAVG-AIDLAIERNRIRGNG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_3757948 +-------------------------------------IQAAINSLPTVFVPAGTYLVDAVRS-----------VKLRSQMHLKLDPGAKLVAKPTSSESYNVVFADVAHDVEISGGQIIGERHQHKGTV-------GEGGHCIRIRGCERVTVRDIRLSDGWGDGITV---GPRPNRRKRFTYSQDVAIANIICDGNRRNGLSIGNVIGIKVYDCEFNNTNG--TAPQCGIDV----EPSPDFDHCDDVHIENCRMSGNGAMNVWKNTSNKNTIEGNKTCGLVTRG-MTSSSITGNTI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>R6FQI5_9CLOT +---------YGVDIQKFNINNNGLNPIETSKGINDALNYAAKNKYDKITFPKGEYCI------SEENP-----ITMVSNLIVDLN-GATFKINDNGLQHYTVIDFSNCSNSQLINGIILGDRETHDYKTIE---GSHEWTCGIVFNNCDNCILDNVTISSFPG-------YGISSSLGENLS-DLIIGVTKENLSIGNINDKGLNNKKGTIIDPLNISNVGGEELGYNKGYMGYPYMQSKEYLSYFYDSKVDNCKQYK------------KVLIPDNYVHFVFKQDY-----------VPERGDTDFNGTTVFLTNYSSPNNITIKNCLIEKNKLGMGIGGYNWNIENNMFKGAPGYAIGWEYMDSFLFKNNKFNNNDIVSCAGDN---IIFENNSFTSTVYMWG----RTTNYKFLNNSFSNIAMNINYEYSTDTECSGNTYAITSK------NKDAEFNINNENIIDPENVSIIDADNIDNIRIYGN-FKDCH----ISKVTGSLVNFRGEKCKINNSN----------------------------------------------------------------- +>SRR4249919_2030177 +-------------------------------------------------VPAGRYLIDAVKS-----------VKLPSNRKLKMHPDAILVAKANNAEGYNVLLVERVDNVQIVGGQIVGERDKH----IGT---TGEGGMGIRFRGATNSSVTDTIVSNFWGDGI-VAG----PYKGSKYIPSTDITLKNVTMSGNRRNGLSVGNVVRFLAEDCKVLDNGNDPDGPFCGVDVE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1S1V829_9FIRM +---------YYAD------AAFTKPATDATQAINSAVKHASQNGIQKVVIPSGNYLIKAEGTGIEGDYAKTGGILLQSNMTLEMSSNAVLVTNTVNKPGYSLITVNNKSNVKIVGGKLVGDKDTH-------PANTHNACYGISINGSKNIYVDGTEITKMEDDGIMITDYAIDQSGG---TRSSDIEIRNVKSHNNGRQGLTI--ATGSNIKILNSEFSNQTKHEPKSGIDIE-----IESYDHVKNVEISGNKFEGNAFSGVSRHAEGKSNGLDMSNNNITVNNYSSGVVISGNNIISD-DSKAH--TSMGVYSTTPG--VSINGNNLVGQNVGMMLSGGGEQIVGNKIENEISVSGAAHLAENLAIKNNNFHDMKSYGINVRNT---EVSGNTMKNITEAFPNKASENTGINVTGNTFDGAYPTLYLGISYANSVKANSFTFSSYGYGM-------------------------------------------------------------------------------------------------------------------------------------- +>A0A1M5UZK5_9CLOT +---------YTIELDKFGIKNDATFAVETSKGINDALQYAKEKGYEKIVFPKGEYLISELNPV------------VIDLKNVVIDNQATFQINTNGLEKYSIIQIDGAENIRLTNGIIRGDKDTHDYKTIKT---PHEWGCGIVFKGGKDLEMDNITVTNVTGYGIYTESGTNSNRFDAVYT-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5687768_13918870 +--------------------------------------------------------------------------------------------------------------VSIRGGKIVGERGAHHGT-------TGEWGMGVRLAGCHDVRIQGVQITDCWGDGIYVGANGVGN-------ESRRIKITECILRNNRRQGLSITGCIGALIRDCEFTDTNG-TL-PASGIDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A250E5Q6_9FLAO +---------------------------DDTEAIQNAINEASKKGGGVVYIPEGTYLIDAKQSLVIRS---NVTLQLAANAILEAKANTILEAKANTSERYDILYIKNVENVKVVGGTIKGDRNIH-------IGNRGEWGMGIGIYDGKNIVIENVSVRDCWGDGIYI---------GKNRNRSENIILEKVKSVNNRRQGVSITAAHKVTINHCVFSQTNG--IPPQAGVDIE-----PNAADTVSNVVIKNSIFDSNENSGILIYTGAERS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_21041421 +--------------------ADNTGSVSTQSAINAAIALQNARGGGVVYVPRGTYLIDT-------NYLTGGSVRVLSNVTLHLDPGAVLQAVPTSNGQGAIVWAYNAENIIIQGGYIRGERDGH----IGTDQP--DGNHGISIFSCDNVTVKNVRVSHCWGDGMYIRNDTGGNNTG--DTLSTQIRVLDSSFFNNRRTGLACVAVDGLTISKCYF--YGNTGANPYAGLNLEPNSDGWVR-----NCVVSDC-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1H9W652_BUTFI +---------------------------------------ASNGGLNTIYLPAGVYNITDIGNYDH-------GIELKSNVNLIMDKNAVLKVSGMPYGDYEIFSMRYLSNVTIAGGQLVGERYSHSYG---------ESGHGIAMHGCSNITITNMCISANWGDGIYFGTQAVWLGSGQGYFGNTNVTISGCDIFDNRRNSISFTDADYITVDRCNLRDSHG--TAPQCCVYFEPNGDSSDK-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR2546423_4745973 +-----------INVRDWG--ALGDGISDDTPAFAAALATLADRG-GTLSVPDGDYRIDPLKS-----------VRLTDNVALNLSRDAILRAIPVTARNSAVVLVERARNVRIIGGTIIGERDGH----LGVGG---EGGMGIWVSASSNVRIERVTALDCWGDGFYIAGRGSYDANSLHESHSDNVTVSRCIARNNRRQGLSVVGCIGGLIERCGFTDTNG--TAPQSGIDIEPQG----------NWTVSNVTV----RNCVTARNAGWGIL---VCGNDIYNASVSDILIEGNR------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6185503_5510564 +-----------------------------------------------VDVPAGRYRIDPVRSIHLADSEMASGAVLAA-LPVAQGNSAVIRL--DGIQGAS-----------IRGGMIIGERDGH----LGT---AGEWGMGIQIMGGSTISVEGVRIEGCWGDGIYVG--------GRSGVEATHITIRRCVVTNNRRQGMSMTGCRDSLVEGCTFASTHG--TAPQAGIDLEGYGLSGGREQHVQTITLDDNRVADNG-----FHGIGVVS--------------SVDCSVRGNTVEHNG---RDGVQIAGSSRVRTGNTIRDNSRRTAGVWDNVIV--QSLSTDNTVANN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1E7DPH2_9BACI +-----------INITDYGANADDSK--DDTSSIQAAIDAAAGKN-GIVLIPAGTFLINT-------DPET-GSLNVKDNIEINMDEKTILKSIPNGLPIYRMLTIYNRENVKITGGTLIGDRYKHEGT-------EGEFGHGIYIGGSSEITISNVRAQDFWGDGFFVEGNASQTYP-------SSITIDNVESHNNRRQGISITAGKQIVVKNSIFSGTNG--TPPAAGIDLE--------RDPPYSLPLEEVELLNN-----------EVFNNEGY---GISFIYASNSSAQKNIVKNKGGIYIGGGVEQGIAKNNT-----VDDNFISENGLGIFVNSTQNNISNNVIEKSKKDGIVNHVGQN-RLVKNLVRDNQGNGLYIHDQSGIVVQQNKSKNSKAGIAVNVLDATITD--NDLLDNAGAGLHREEAKESTIERN------------------------------------------------------------------------------------------------------------------------------------------------- +>F3B2U2_9FIRM +---------------------------DDTAAIQRAIDAVSAAGGGIVDIPAGNYMI---NTLHQTGHSYRAGLVLKSNIIVRMANGAVLRAIPNGERSYQIFSITHVDNVHIMGGKLIGDRDTHIGNLGQT-------GYGVRITDATNVVIEDLYAGEFWGDGVFLG------------EDSRNITLYRVICDHNRRQGMSIVGGHNVKILESEFKRS--DGTPPKSGIDIEPEG------DHPIGVEIRNCLFEGSSTGFVVSNQSNSVAENIIFADNI----------VRGNKT---------AVNLVGIQSGETGNTISITEN------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A177L0L1_9BACI +--------------------------IDDTDRIQKTIDFVNKKGGGVVTFPKGIYLIDA---------EI--SLKLKDNITLKFEKGAILKALPNNAESYEIVKIHDVENVSLLGDTIIGERKEH-------IGKTGEWGFGISIRGAENITIENPFIKDCWGDGIYIGATTKKKY-------SKRVTIINPLIENNRRQGISVISAVDLTIISPKLLNTNG--TSPQGGIDFEPNSEN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A150W909_9BACL +--------------------ATGNGEVDDTIAIQNAIDFAYSNGNKTVFFSKGIYLVDSSTSL-----------VVKDGIVLKFENEAILKAIPNALERSEVIRIHDVKNVKILGPEIIGERDEHLGS-------TGEWGFGVSIRGAENIYIENAKISNFWGDGIYIGSTAKKNY-------NINIEINNVELTNNRRQGISIISVENLLIKDATITNTNG--TSPQCGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1G2XYR5_9BACT +--------------------------------------------------PSAVYNIDADGTGDQ-----SAGLKLPSDVNVAFEEGSKLKVIPNSSTVYSVITITGKNNISLSGACIEGDRNFHTGT-------TGEWGFGISISNSQNITIKDVNVYDCWGDGIYIC------------SVSDRVTVRDSIFNHNRRNGCSIISAKNVLFENCVFSNS--DGTSPYKGVDIEPNYENCRSYNNPVSITFSNCSSDGDGTGAGPRNTLGTITFRDCTSTNAVENGFSINTVIDGLYIVNPG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6478735_8854003 +-----------VDVREFG--AKGDGRADDTDAFEEAIEALPAGG--ILDVPDGDYMIDTLRSIRLRD---GIHLRLARNARLIAQPNAA----PRSY----VILLRNVRDIRITGGAIVGDRDRH----LGLDG---EWGHGIAIYSVRNLVISGIHISKCWGDGMSIG--GKSAQKGQPATPSMDIEIANVTSVGNRRQGLSIGRSRRVWVHDSEFSGTGG--TPPQAGIDVENRGPGIQVWKDTHDVSISDCTIEDNRNAGILAVDATDVTIRDNRIRDNTQVGITRQVSISGN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1C7EEP3_9BACL +--------------------SYGNDKMDDTQFIQNAIDFQSSKGGGVVYFNKGEYLIDSTKSITLRD-----------NITLEFEQGAILKAIPNSAERYEIVKIHNVKNVNITGQSIVGDRSEHTSSL-------GEWGVGISIRGAQDINIENVSISDSWGDGIYIGNTSKKNY-------SENIKINNSNFDNNRRQGITVVSVKKLEIINATITNTNG--ISPQSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1I2HG07_9BACL +-----------------------------------ARINAAINSLPTVYIPEGTYMI---NTGNPYNPVTNATISLKNNITIKMTENTVLKAITNAYNNYAIFLVRAVSNVTIEGGILQGERYTH------TGPTAGQVGVGVWLEGATNVTIRDVTCKEFWGDGIYTLYHSTLG-------NTKKVTVENVSFIDNRRQGISICANENFRVIGCSFEPAAGIDIEPELGVTITGNVFKGNKIGGDASATITGNVFEGNTMGIYLASSSRYYSVTGNIVYASGNYGISTDNVISGNVVYNNG--------SHGIYLLNNADRNVITDNKVYGNS------GEGI----NVYKSFDNII-----------------------------NDNNVTNNKGRG----IFIAVSTDNSING-NTSSSNALSGIYLWNSKYNLVDSNRCSKNGQ-HGIFVKGDAANDSLSNSI--------------SNNQCKENSQTTNQGYQNIFLSSGAQGANTINNVQGNMCRAGGYGILIDNTSETLLKNNDTRGGGAK-------------------------------------- +>M2U1I2_9SPHN +--------------------------------------------------------LDVVSPTNGRR-----GLVIPSGSHWVMHPEMRIRALPNASSHYEILNILDEEDIVINGARLIGER--------DTHRGAEEWGFGLSVRGARNVLVENLIAEDCWGDGFYIGS-GRRKY-------SQDILFRNTKAIRARRNGLSLISVRGFLSEDHESAHTFGSA--PQWGVDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690349_1434838 +--------------DVTSMGALGNGVHDDTAAFQSA-IDALPADGGVIDVPPGTYMIDATHTCPGRGTALQCGLILRSHVALSMDVGAVLRVIPNDQERYYAIYVRGLSDVEIVGGRLVGDRTTH----LGT---TGEHGYGIAIAGSSNVRVRWTEVSNFWGDGFIVSRTGGDTNP----TYSRYVTLDHVKSSNNRRQGLVAGGVQYLLVQYSTFRDSNG--TAPEAGVDFE--------PDEPTVAPVSDIRLYDN--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_575702 +----------------------------------------------------GTYIING--ELEGHTYESVGGIILHDNIILQFAEGAILKVMPSESEFYSDITLKDCNNVSVLGATIYGDRSEH-------RGVTGEWGHGVKVIRGENINIKNVRVSDCWGD-------------GVYFRDTKNVTVEYVISDNNRRQGMSIVGGENIYVRSSVFKNTNG--TQPETGVDI----EPNHDYQVVKNISFNDCSFHDNVSKGLMLFTNGGT-----FEDIVVN-----NCSFSGN-----------GAESFRVSGRGNHCNIKITNSTLEHMALGTSA---------THVLNAS--------ADNVIITNNYID-----KIVLNNTSNSIISKN-----IIIENIVLVDSNNIRIENNIFNDLYDEVYDDASKYIYITNN--TISGGKRGVF--VQSTEFLSLYSTINIKNNMFIGLTE---------------------------------------------------------------------------------------------------------- +>SRR3546814_95907 +-------------------------------------IYALPSTGGTVVVPDGTYMIDAVRK-----------VRLRSRMHLKLSSGAKLVAKTNSSPRYYVLDDGNASDLEISGGQIIGDRHRHTGT-------TGQWGQGIMIRGCRRVTIRDMRISDCWGDGMSISSI-RLNGRYDPWTPSNDVVIANVVSTGNRRMGLTLGGTRNIRVHGCEFSNTRG--IEPGCGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>R6GIV0_9FIRM +-------------------------------------------------------------------------LTVHSGQRLLFD-AATFQLTANGYDFYAVLNIHNVNNVTVEGGTIIGDRESHTAT-------TGESGHGIRIVNSHNVHVSDVDIRYTWGDGVCVGGNGTM------AEISQNVTLERIRTYKCSRNGLSIIEADGVVVRDCDFTYT--DRTAPQYGIDVE------PNLGTATNITIENVRMLNNGIGGFALYTT----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A088F0B6_9SPHI +-----------------------------------------------------------------------GGVALSSNTIVYGNNAKITAFADYNQPAYNIFRIENIENVIVKDLELIGDRNSHTGTL-------GEWGYGIAVLGSRNILLNNVVSKNMWGDGVNIQMLN-ANQAGVTQTHCSNVTLENCIFSNNRRQGLSIEDGSTIRVSGCTFDKSNGKA--PQCGIDIEPI-VAGRAFVD--GVTIEDCMFSDNNSGILMESLNGPISHKKAKISNAVYIGINTSRNNLNTKIL--GNTFDKSLDTGGMYMAISGNYINSTDTNLPEFYTDNLV------IDNNTL--LSGLTLESGVRK-VTISNNKIESPNTSSIGIFNKSQRLIANNNNNCETGIHSYNTTTTSAI-INENIFKNINIGVVAQLNS--KIISNQFINTGSGYG--------------------------------------------------------------------------------------------------------------------------------------- +>SRR5512133_1390 +-----------------------------------------------VSVPDGTYMINALTS-----------VLLKSNMTFSMSSGAVLKAITNSSSNYSILFANGVNHVNIIGGTIQGERTTHTGT-------GGEWGFGVRITGSQQIVVEKVLAKDCWGDGFYVSA-------------SASITLCNVTADHNRRQGLTITSVDGMVVRNSTFKNTQG-TL-PEDGIDIENAGET------VNNVLITGCTFTSNSGFGV------EIGVPISYTGQAWIKGVVVDNTVTGSGVNTLSTSPRAGIEASDIPS--AGNK--ITNNYCANNGLGILLRSNGMTISGNTVTQNTTDGIQVYSTDGNTITGNTATNNLGRGIYSTSNTNISISNNTVSG------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1X6W0S9_CHLAO +---------YLIDVNEWGISNDGTNPLETTQGINNALQWAYQNGYSYVKLPEGVYTVSKGSASKDYSENACILLQNDTTLDLY---GCVIQKEANGWDYYAAISIVEKRNVTILGGKIVGDHLAHDYATL--ANSIHEGCIGIIVRGSRNITLNGVEV---------------MNFPG------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>ERR1035438_889792 +-----------------------------------------------VMVPDGTYMVNAV-------AQNAAGIRLGSKMTMKLSSGAVLKAIPNASGNYAILAVSFASHVTIVGGTLLGERGSH----TGTDG---EWGMGLSINNSAHVVVQDVTAKECWGDGFYVT------------SLSSDVTLCGVVADHNRRQGLSVTSVEGLVVRNSTFKNSVG--TAPECGIDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>WorMetHERISLAND2_1045183.scaffolds.fasta_scaffold180453_1 +---------YYLDPVVAGITVSDTIALANTVAINTALETAKTEGNTTFVVPTMDAYFDTGGNGNSREEEVSGAIQIPDNMHFKMGAGTVLRRQPNDNRGYGSL---LGENVEISGGTLIGDINDHTYVLMDDDNTTFEFGFGISLYGAHNTYIHDITIRNFHGDAIFIDKTGLRNIDATLFRTCENVLIQRAYMQNNRRQAISVVDCNGVIIDNCDIVDTGRDIYHPAYGIDLECYRQLGAEYARVENVIIKNSRFSGNRKGDLNLYNSQYVQVFNNEFTYKIGHVASNNVSIHDNTFTYDPIVYPENTDSVAISITELVYDFDIYSNTISGYTFGIIVSGDRFNVYSNNISN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_498154 +-------------------------------------------DFGSIVFPSGTYMVDG---NDPAGPGGRQGVRVPSNRAISWLDGAEVRVIPNSNTGYNAFLVDQVENVLFLNPRIKGDRDEH-------TGVAGEFGMGIEIRSAENIVLRDPYIYNCWGDGIYI---GQVSEAA---GPCKDIYIERGKVDNNRRQGMSVISVDGLFVDNTQFTNTNG--TPPQAGVDFE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A0Q9EPM5_9GAMM +----------------------------------QAVIDALPADGGTVYVPAGNYIIDPTRNLRLR-----------SNMHLQLADGAKLLAKRNSADRAYVLMAYKVSDVEISGGQIVGDRDNH----LGT---TGEWGHGVMVRGSSRVTIRDIRISRCWGDGISVGGAIVTGLPTVI---SQSVVIANVASTGNRRQGLSIGRSSEIKVYDSEFSDNVG--IAPGCGIDVEGNQGNGQVYKRVKGITIKRCTIEYNGYGILTAPVSGYIAIAHNYLMGVMLRSATTSYQVSGN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2G6EWH0_9GAMM +-----------IDVTDAGYDAKGDGTTNDTTAIQKAIDAVADAGGGVVWIPKGRYMIDTEARLKMR-----------SNVTVQMTDDTVLEAIPNGAGSYSIFRFYNVENAHLLGGTLVGDRDSH----LGT---SGEWGTGVNISSSSNIRVENIVTKDFWGDGFYIGENGSLD-------KSENIVLYNVVGDNNRRQGLTIVNGDNIKIIDSTFQNTHG--TAPAAGICIEPNDNN-----LVSNVEILNCKTINNDGDGIGLYE--RVNAINNEIEN---------VRVDGNEIINSGGIIVSG--SV-TDSTITNNFINTTDSSEPGIRL----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_10317103 +----------------------------------------------------------------------GASIRLHSNSQIVIAPGAMLRAIPNNLNNHALFYCYDAENVYVTGGTLLGDRDDH------TDAEDGNAGMGWRISASSRVTVERQRILDFWGDGIYV-RNGTVETED-YDTLSTQVEIRQVECNNNRRTGIAAAGVEGLTVWKCWLRNTNGANAGANFEPNIDGYGNAGAGFQSGHDVTFDACTGRGNGNGFRILNTTG---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>S3Y1Z0_9ACTN +---------------------------DDTAAIQRAINQASDAGGGTVNIPGGTYMIDSVHGLMMRN-----------NVTLKLADDAVLKALPTNTTHYSLISFVKVENANLVGGTLIGERYQH-------TGQGGEWGHGVNIQSSQKVTVQDVTSKDFWGDGFYIGQAWQV-------WDARSNQVALCNVTNNRRQGLSIVDGTNIRVLNSTFSRTNG--IAPQAGLDIE--PENGNLVEN---VEVRDSVFSENGDGI------------------VLTWGEQNDASIKG---------------------------VRLESNQVLDNESGIMLRAIGCQVINNTIRNAGN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_4714463 +-----------------------------------AIDYAVEKSIDLVWVPKGVYMIDAAGVNGEK------GLRLRSGITLKLHEEAVLKAMPNNVANYSILRVYDSANVKITGGSILGEKNEHTGT-------GGEWGMGIDIQSSNNIEISNVKVKECRGD-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1041385_954775 +----------------WG--ALGRSSPDQTKDDTQALQAALDSGARKVTIPNGHFMIDAARVQPGRTK---AGLNLPSNIELIMGTETFLHARNNSSISYNILVGWKVSNVIIRGGVLVGDN-------VTNSRRSNPSGFGLALFGAKNVWVYGLTSQEMFADGFFVCYD---DEPGS-HDECENVHLMDCRAYKNYRQGASVIGAKNSSIEGGQYRQTGGSP--PQDGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5581483_5383682 +--------------------AMGNGSMDDTKAIQAAIDALPESGGTII-VPNGTYMIDALK-----------GISLRSHDRLSLASGAALKAIGNSERRSWVVKVWNVNNVEIVGGGVIGERYSH------RGTSGGEWGYGINISSSDKVYVHDITIQDCWGDGLLIGALG--SGKGMV--EATNITLNRVKSKNNRRQGMSITPANRVYVVNSSFTGTHG--TAPESGIDIE---PRSQGWASQVRLENTDLS-NNNGNGNVDALTLYKVTAKNN--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1G7HPV6_9FLAO +------------------------------------------------------------------------GLRIRSNSKLYFQKESLLKLKSSAKVLYAILNIAKVENVSIYSPTIEGDRYRR----VNPEDKKGEWGMGIWIQESKNISVFNAKVTHCWGDGIYIGG-------GRDIVPNDSIYIHRPIIDENRRNGISITSGKNIRIIEPVVSNSRGKS--PESGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1G2Y1Y7_9BACT +-----------------------------------------------IRFPAGTYAIDGFDTIDKGNVTVYGGLKPASDTTLIFDIGAKLKAIPNDKIGYSILKIEGKNNVKIYGPTIEGERDSHTGT-------TGEYGMGIMLEGATNIVIKDANVYNCWGDGLLIGVHWT--------KPSDQIYVENSTFNNNRRLGCAVTNGTNILFKKCTFLNSNG--TAPQAGVDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1035438_766262 +----------------------------------QACINAVAGTGGTVVVPDGTYMI------NATHGSGVWGLMMGSNMTFAMTSGATLKAITNSSTDYGILCSNGASNFTITGGNIVGERSTHTGS-------GGEAGMGIYLNAS-NVTVSGVNVSECWGDGIYIC------------DASSNITITNCISNHNRRQGLSITAGNTFLISGCTFSNTTG--TDPQCGIDIEPNGSVPVTGVH-----ITNCQIFGNAGGGVQQGNVGNV---------------ASGTLLENCNIYSNGGG---GYNDGGIRFVETHDNI-IRNNNIHNNLNGMLDTNAGIGCPNNTVANNSGWGIYANLCNGSAITGNTI-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_3394488 +----------------------------------------------IVDVPAGTYMIDAETSILMRD-----------NTHLRLATGATLKAIPTSSAVYNVILCELVDSVEISGGAILGERDAHTGT-------GGEQGHGIRSRGATNVYIHDIHISKCWGDGI-DAGPDKSDSHNYVYT--ENLTIDNVVCTQNRRNGLSIGNVNTARVTDSEFSYTNG--TSPQCGIDVEPDGDADGDGDCS-DIVIDNCRLNNNAVYGINLYQRARVTISN--C--VIEYNSSCGIVSNG--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_325582 +-------------------------------------------------VPAGKYLINPVRVASGTS---FYGLLVGAGKRLEMDPNAVLVLKPNSAPRYCGVRI---DGGYMQGGQVLGDRLSHNYS----SGGTHEWGYGVQLRGTDSKAV-GVKVSQCTGDGF-----GMSGI---------RPVIENCISTQNRRQGVSLFGSDGLRISGCEFSNTGAAGTNPRCGVDFE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1E8BK68_BACMY +---------YFLELERWNVKNDGTDANNTSKGINNALLWASQQGFIEVVLPMGIYLID------ENTP-----IEPQSFMTLNLG-GATLKIRDNGLVKYAIVYQRNQKFSRITNGRIEGDKDTHDYTTIP---HTHEWGYGIEVEGSSYISIDNMEILNCTGDGI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>SRR5512142_681238 +-----------------------------------------------VYVPRGTYLV-----LADGYRDGGGGLAPRSRTRVVLAPDAVLQARPTGSSDYVVVRIERVSGVTVEGGTIRGERHEH------TGRGG-EWGFGIGIFGASDVVVQDVTIRDCWGDGLFIEE----AQPDFSVMP-RNISIRRVVSANNRRQGMSVPG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>D7W8T5_9FLAO +-------------------------------------------------------------------PLMTSGIFAQSNSQIYFQKNSSLILKPTADVRYQIISLHAVENVKIYNPTLIGDRDRHLGS-------KGEWGFGIDIRGSRNIEIYNANISDCWGDGI-VLVKTMRNMRSGVIFPTENINIIGGFINNVRRNGITIAGGKDIIIKNLLIANING--TNPMAGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_487370 +------------------------------------------------------------------------GIVLSSNTNIYFDVNSKLILKQSSKESYSMLKIYNVENVNLFNVHLVGDRYQHIGS-------EGEWGMGIRIQNAKNINIYNSTIRDMWGDGIYITSFG--------NTSNQNILIQSSWIDNTRRNGISIISGEDINIDYVKISNTNG--TAPASGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>H6LBC8_ACEWD +-------------------NAKGDGKTDDTSAIQNAL-----NKSDSVYIPDGTYMIN-----------VDQSLKPNSNQTITMNANAVLKAISSSRGEQYVITIDGVTNVSIIGGKIVGERNEH--QGLDG-----EWGMGINVNGSSNIVIKDTTISDCWGDGIYLGGSPAVN----------TITIDGVTSDNNRRQGLSITNAKNVLINNSVFKNTNG--TAPEAGIDIEPYGNNQSGIDGIQRVEITDCTIKDNGLGILLFEASGNTSVTNNKDDGV---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6185312_3767693 +------------------VGAVGDGTTDDTWAFQKAIDSVAAQGGGTVYVPAGTYLIDADVSINMKD-----SVTLD-----MVDTTRVLMAKPTATVRNYVIKLNNISNSKVIAGKIVGDRYQH----LGT---TGEWGMGMGINGSTNITVTGTNIIDCWGYGITISSYNCV---------LKNVI---CD--NNRRQGLTIGSSDSLIVDSCTCTHTNG--TAPQDGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A0D5BSE2_ELIMR +------------------------------------------------------------------------GLVLNNNQVLLFQEKSVLKLNPTTQKEYSVLGLSNVNNVKIFFANIEGDKYQHLTNV-------GEWGFGIGIFSSNNISIYSPYIKQTWGDGIYIGQ--------IKNIPSTNIQVYNAVIDDVRRNGMSITSAKNIDVVNAYISNTNG--TSPESGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_13262863 +------------------------------------------------------------------------GLKLRDNSKVLFQQNSVLILKPSSKSQYSIILMDGVSNVKVYFPKIKGDRVGHKGT-------KGQWGMGIWINNSQNILVHNPYITNCWGDGIYLG--NVNNRP-----PNKDIQIIDGMLDNNRRNGISIISGRNVEINGTFISNTNGHN--PQSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1035438_2623855 +------------------------------------------------------------------------GIRFGNNMTLRLDSGAILQALSTSSSSYRILLLSGVQNINIIGGTIIGNR--NNNTITDSV----EDGMGIQIANSQHVVIEGVTVQDCWCDGVYVS------------DGSGDVTLNGVVAKNNRRCGSAIVSVSGMVVRGC--------TFQGTTGMMENGLWANGTGVDVEPNLTVQNIQFLGN---TFTQNATGGLGIGPSNAN--MATTFVINCVIDGNTVSSNGDAVK---GTFGIVASSTGGH-QILNNTVNNYGVGIYLYGSNILIQGNTVSGTS--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2A8TS41_9BACI +-------------------------------------------------IPDGTYMI---------NADI--SLKPNSNQILSLSKKAKLKAKPNSDASYQIINIIEKENVIIEGGYIEGERDEH----VGVNG---EAGMGISVRNSKNITIRNTHISKCWADGIYIGG----------YLPCYNINIYNVTCDNNRRQGMSVVNVDTLTVRDSFFTNTAG-TL-PEAGIDIE--PEN---YSTVKNVTIDNCTGNRSGLDVFWAKTISNVQVLNSSMINNREYGFTTDILV----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5687768_6663082 +-----------------------------------------------VYVPAGTYLVDATRT-----------IRLRSRMHLKLDPGAKLLAKATSADRYYVVNAYKVHDVEISGGQIVGERDRHIGS-------SGQWGHCIGVRGCKRVTVRDIRLSKGWGDGISIGAAN-----GTTTVLSDDVAVANIVSTGNRRQGMTIGRCRNVKVYDSEFSYTSG--IKPGCGIDIE---------PDPFTIRIQNCWIHHNGNGVQVYKTVKNVTIK----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_2031064 +-----------------------------------------------------------------------------SNSYIKFHPDAVIKVNPNNYGDYDRKYIYMKDNIVIKNPRIVGDKHEKNYKKIDSE----EWAAGIQIRKSNNIKILNPHITAMWGDGISSAGRKSMGEP-------DNILISNCFIYDNGRNGYSITASSNTKVFGGIISKT--DRTEPISGIDVE-----PAQYSRDVSLNIKDVKF-TNGRGLILFKASQGAVIED---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5688500_1121635 +---------------------------------------------------------------------------------------------------------------IVGPGRITGARMVHRGS-------SGEWGMGISAWNSTNFRITGVEIADCWGDGIYVGSAGNGYCDGFLI---EGVKVRNC-----RRNGISVVAGRNGEIRNLDIAKI--DGIAPRGGIDLEPNSSNAPNRN----IRMSNGRIRDVAVGIYVTVANQRVSISDIEAENIIVSDNSVDVRIENNPNIKSIGGKEGGAFRTVVTRPETIRGLLIRNNQLSGFVIDIFGQGQGLVISGNRISNAGTQGIA---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_32025263 +------------------------------------------------------------------------GLKVKSNSVLEFQENSLLKLKASDKHTYNILEIHSVQKVKILNVKIKGD--------LDTHGKDGEHGMGISIRSSKDVEVVNAKIEDCWGDGIYIGRLNRYDRNGM-FEPSENIIIRDAYVNRNRRNAISITAGRNNLIDKLDANKTKG--TFPIIGIEIK---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5579883_944156 +-------------------------------------------------------------------------IQLRGRQEIIFEPGVVMLAKKGEFRGTGDSLLSIVSNLVLRGYGAILRMHKPDYQA--EPYKKGEWRMGIAIRGCKNVLIEGLRVESTGGDGFYVDGGADRGW-------SEDITIRNCTAYDNHRQGLSVISAMNLAVENCVFASTRG--TPPEAGIDLEPDTEENRLVN----CLIRNTVFQNNNGHQVLIHKSMPVSIRFENC------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1T3DZL3_9FLAO +---IKKDGSYYERQFEGGINPAWYGEL-TEKSINKALHIASVLN-------------KDVELMNDYKIDCSGGVKLLNNSVLRFSNNARLLAIPSSSGNYRMLSIDKVKNVKVYNPVIIGERSAH----LST---TGEWGYGINITNSQNVEIHNAVVKDTWGDGIYIGG-DYFDKTQTISTLTDNVLIYNPYIDNVRRNGISICSVGKVRVYNAVIKNVNG--ANPQSGIDIEPEGDTG---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_10516162 +-SLLDRIVLYVDDF-----GAVGDGVSDDTDAIQQALNVAGELRTSVIFTKGKTYMTDG-----------SKGILPPSYSTLIMTGSKL-EVIPNALDRYICLYVLIAEHVTIIDPDLKGDRSNHSTNNNNVDGFTGEWGFGLRIARSKNVNVYNCKTSDFWGDGVLIGTDGIENTP------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5262249_48802186 +---------------------------DDTSAIQAAIDAVAEKRGGTVLVPNGTYMVSAVR---------DNRLSLKSNVTLRLANDAALKAIPNDSDHYSVLRIANVSNVAVIGGTFEGDRNEH-------SEKTGDWGMGIWIKGAEHVTISGVTATKMWGDGFYI---------------QDANDVRLCSVENNRRQGLSIIQVNGLEIKNSTFKNTHG--TRPSAGIDIEPDNDE----QHVANVRIHDSKFLDNGAGIAVVAKKSLVS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1700750_2813068 +-----------------------------------------------VEVAAGEYLID-----------VTKSVKLRSGVALVLDPDATLRAIPTDAGNSAVIRIHDATGVRVEGGSIVGERDKH----LGTNG---EWGMGLGARGSHDVLIQDVLISGCWGDGVYVGS-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR2546423_7159601 +--------------------ALGNGVVDDTAGINAAIRSLAGTGGSVL-IPAGVYLVD---------PTV--SVQMASNVSLLLDDSAILQAVPVAAKSYAVIAASGVHNVKISGGKIIGERQTHLAA-------TGEWGMGVRVMGSSNVQIERVE--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5680860_103890 +-----------------------------------------------VLVPNGVYMVQAV----------GESLALGSKMTLRLADKATLKVIPNGETRYYTLRIHEASDVTVIGGTLLGDRRAH-------KGKKGEWGMGLHIVRSSRVTIAGVTSTRMWGDGFYVA---------------DGTDIAFCSVANNRRQGLSIISANRLLVTDSVFRDTRG--TRPSAGIDME-PNKASQRIAH---VRIERSKFIGNGDGIVIQGYKGRVSIRNNLFD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A1Z4RLG8_9CHRO +------------------------------------------------------------------------------NQKILFQPGVVLEAQPGAFKGYESMVSVMADNVTLSGYGAEFKMRKADYANPSLYEKS-EWRHNIHVRGARNFIIEGLTLKDSGGDGI-LVEHGPNEPNQLPVSKYSSGTIRGINASDNYRQGISVVSAKDLLIENSTFQNTSG--TEPASGVDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2B2C9D0_9BACI +---------YILELDVWSVSDFNDKTLSTSNGINNALTWASQRGYSEFMFPKGTYLIDE-------------NIPIPKNFMTLNLNGSTLRIRNNGLPKYS--VICYRQNQIVTNGIIQGDRYDHDYSN-PGELPTHEGGMGILFPNTTDTTIDNIEFLDLTGDGV-----SLFSSQGLVYTPTKSYAI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2C2T0P3_BACME +---------------------------------------------------------------------------------------------------------------------------------VDNERYTHEWGQGIEIAGSNHVEIKNIEICDCTGDAV---STGWLKYNSTDYTQNEHIWIHDCDIHHCRRQGITLASANDVCVYNNKIHHIGRNGIPPMFAIDIESVGESNIPYKQPYRLYIFNNHIHDNQRGHFVNADGNHVTVENN--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5215813_7905647 +-----------------------------------------------VFVPKGVYVVDAV--AKKRRLTLG------SDMTLKLDNDAVLKAMPTDSRKYSILTVSGVSNVTIVGGTLEGERAQH----MGNDG---EAGMGIRVGGAEHVTVSGVTSRKMWGDGFYVEDANDTKFCG--------------ETSDGRRQGLSIIEADGVLVTDSVFSNTHG--TRPSAGIDLE--------PDHPSQIRIQNSKFLNNGPGIEIAGKKGLVT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6185312_5921845 +----------------------------------------------------------------------------------------------------------------------VGERQNHVYSGIGTG--TDEWCFGIQILGVTGMTIRGTQISQCTGDGIDLGNFGS--------SISSDIVICDVISTQNRRQALSITGGDGIFVYDSEFSYTNG--TAPLDGIDIEPGGAGAS------NITIENCLIRGNGCGQLNAHWGDIINVNVKNC------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690625_4101829 +------------------------------------------------------------------------GLEIHGNSTVFFDEGSVIKALPTSNGNYSILSIKGVDNVKIYNANIFGERNEH-------QGDTGEWGMGIRIEDADNVLVVNLKVSDCWGDGIYL---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1H6XJ90_9FLAO +------------------------------------------------------------------------GLNLRSNSVLVFQENSYIWLKASSKPNYGVINIKDIKNVTLINPRIVGDRDSH-------LNKIGEWGMGINILNSDYINIFNAIISKCWGDGIYIG--------NKINGFSSNININGGLIDNNRRNGISIVSGEVVVIKDITVSNTNG-TL-PMSGIDLEPNTNEDTLKDIKL-VNVNSFNNRENGLGGLLGENKREVDISDQYSNTVVSIGLRNDYEKKVKKI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>SRR5512133_257377 +-----------------------------------------------VTVPDGTYLVNALTS-----------IQLRSSMTLSLSGGAILKAIPNSSSSYTILRISGVSNVNVVGGTLLGDRSAHAGT-------SGEQGVGLRITGAQHIAVVGVTSKECWGD-------------GFMVADASDVTLCNITADHNRRQGLSITGGNGIVVKNSSFINSQG-TI-PEDGLDIE--PNSGQIVSN---VLITACVFANNAGDGI---ENGVPVL-------FTGLAFIYNVVIDGNTMTGNGVGTLHAGPRSGIEVSNTSGHV-IKNNTIQGYGIYLRDGVAGTTVTHNTVKNALN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A110B3A3_9SPHI +------------------------------------------------------------------------GLSLISNSTVIFRKYSKLVLQANGLPAYQILRIYNATNVNLYFPVVQGDR--------DLHSGNGQWGMGISISGSTKILVVNPKVSKCWGDGIYL---GRQN-----NAVDRNITIFYAELDNNRRNGLSITCADGVHLIRPIISNTAGQM--PMSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A229UP75_9BACL +---IGSPVSYAIELDRWGIQNNGTDAETTTRGINDALVWAKSAGYNHVVLRGGTYLI-------QVDPN-GTAIYMPSGMHFEMHHDCILQLAGNSFPNYRMIEMKGIRYAKVSGGKMIGDKAFHQYEM------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5262245_13989197 +-----------------------------------------------VVVPNGIYLIDAAGE---------NRIKLKSDMVLKLSDGATLKAIPTDAENYALLTIADASNVWVIGGTLEGERDRH-------KGKSGEWGMGIRIEGAKYITIMGLTSRKMWGDGFYVRG---------------AEDVRLCGVDANRRQGLSIIEADGLLVQKSVFKNTRG--TRPSAGIDF----EPNRDSQEISNVRIENSKFLDNGAGILVAGKKARIT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5215831_1849565 +-----------------------------------------------VLIPAGTYMVNAVDS---------NRLSLKSNVTLKVANTAVVKAISNDSEHYSVLRIANVSNVAVIGGTLEGDRNQH-------LGKDGEWGMGIWIEGAEHVTISGVTALKMWGDGFYI---------------QDANDVRLCSVENNRRQGLSIIQVDGLEIRNSTFKNTHG--TRPSAGIDIEPDNDE----QHVANVRIHDSQFIDNGAGIAVVAKKSLVS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>OrbTnscriptome_3_FD_contig_123_161973_length_414_multi_3_in_0_out_1_1 +-------------------------------------------------------------------------VKLRSNINIVFEKGVVVEASQKGNAKYPMFEVKNVSNVAFIGGDKPGDVYIGKYRDNEERRRCHDYGSGFAIEGAQNVVIRNVKVAECSVDGISLSSLGRLN---------SNIYVQDVILDGNYRQACSICNADGLYFKNAFLNTSGGD---PMCGIDLEPTYE----LEPNSNIYLFDCRFEGNVGGGLTSSSYYPVTLHAKRCD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>SRR5262245_2037218 +-------------------------------------------------VPNGVYMVSAVE----------NNLKLKSDMTLKLAGGAVLKAIPNDATHYAILTISGVSNVWVSGGTLEGERSEH-------RGKLGEWGMGIRIDDAKNITIAGLSSKKMWGDGFYV---------------QEAEDVRFCGVDANRRQGLSIIDANGLLVLNSTFKNTRG--TRPGAGIDLE-PDKDAQQITH---VCIENSKFFDNAGGGIMVAGNKKARV------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A0D4DCI2_9CAUD +--------------------------------FMVGYIYATSKNRPVVDIP---IYVQSTRKQSGFYNQVHYAVVAQSNSILWFMPEGLIQIGVD-EAAYSILSLYGADNFLIKNPKLRGDKY-------TKTGNTGESGFGLTVTGCSNGIIEYPNISECRGDGIYLGQEYFNNNASSLI--PKNIKIIKPTILDSYRNGLALSAGEDIYFDAPFIDIAKG--TAPEACIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5688572_15557399 +-----------------------------------AAIQAAINSLPVVSIPAGTYLVDTTKRINLR-----------SLMLLSLASGAVLKAKTSSVRRAYILNVNNVRDVEIAGGQLVGERDTHKYVSGTTD----EWNHGIAINGSARVTVRDIRISKC----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6266566_4873650 +-----------------------------------------------IHVPPGTYSVDAV----------SGSINLKSGITLDL-TQATLVANPNNQIFSIIMRVSDCENVTILGGTIRGERTTH---LGSTAAFMGGGGGGVAIWRSKNIKIQGMKISDCFCDGLLVWHSGQVEIQGMSLVDSHDVHIHNSQFTHDIENDLETETCANILVEHC----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>G2KPW0_MICAA +---------------------------------------------------------------------------------------------------------------------------------------------GIEVQGGKTVTVSGNNMDDVRGNGIQISSQGAVNHGIVVNTAPGAVVVDGNRVTDAGEFGIYTNGSKNVVVSDNRVS-------GGKNGIVVQNAAAS-AKIENNVVSGASDAGRVASGYGILVKDSAGAVSVTDNRSNANTGDGLNTDGAVVSGNITNDNGDK-------GIIINRSDNAV-VDDNRSNGNATGIWVESNGVDLTNNVIRHSKVDGIHLRDSDNTLVQGNQINDRNGIFVERSDSADIFRNTITGSGGYTGVKVEGSSNTDIGATDQT-SWVQTGFWPWQGHFVTVRGNTITNFDNGVTVAGGNDNDV--VRNTISVDYGVRLSGAT---NSDVLGNDLTG-NSIVGIEVVAGSHNAVIDNNTLDHFDT----GIVVNGSNNVDVTDNDLTDVGSGIVA----------------------------------- +>SRR6266511_2426516 +-----------------------------------------------------------------------GGLVPRSNTHLHLAPDAVLKAKTTSASDYNVVRIERVSNVVVEGGTIAGERHRHAGS-------GGEWGYGIGIFGATNVTIRNV---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1Q6A375_9SPHI +------------------------------------------------------------------------GLTLHTGQKVYFKKGSVLNLVPTAQPNYEMLRIHDVTNVSVYNVVIKGDKYSH---LV----KTGEWGMGISIRGASNINIYSAKIEQCWGDGMYIGTTPKQAF-------CENINLRYVNCNDNRRNGISVISARNVTILGPVLTNTSG--TQPMCGLDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_4058803 +------------------------------------------------------------------------GLNIISNQILNFSQNSKLIMKTNAEERYGILNIKYVKNVIVNNPNLIGDKEKH-------LGNRGEWGMGINIWASKDVTINNPRISETWGDGIYIGEPPVQE-------------KQKKKLKSYANHNIAIN---GGVIDDC----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6516164_3930632 +-----------------------------------------------VLVPNGTYMVNAVGDAR---------LFIESNVILKLANDAVLKAIPNDSKKYSVLRISNASNVAVIGGTIEGERYGHSGNV-------GEWGMGIWIEGAEHVTISGVTAAKMWGDGFYI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5262245_45879959 +-------------------------------------------------VPNGVYMVSAVE----------NNLKLKCDMTLKLAGGAVLKAIPNDATHYAILTISGVSNVWVTGGTLEGERSEH-------RGKLGEWGMGIRIDDAKNITIAGLSSKKMWGDGFYV---------------QEAEDVRFCGVDANRRQGLSIIDANGLLVLNSTFKNTRG--TRPGAGIDLE-PDKDAQQITH---VRIENSKFFDNGGGIMVAGKKARVS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_56255 +----------------------------------------NENN--VVIIPKGTYRVT--------------GLKLKSNFSLLFEEGAELELIANNKERYEILSLAGIKNVKIYNPVLIGD-------IRKRNSLKGEWGFGIDIRGSREIDIYSPFIKDCLGDGIIIS--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1I0S8N9_9BACT +------------------------------------------------------------------------------------------------------------------------------FATIEGDRSTHQWGMGIAIRAAKNVNIYAPRISKCWGDGIYVG--------GLKGVTSSNINIYNAMLDYNRRNGMSITSVSGLKLVAPVISNTYGQT--PMSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/test/unit/data/small_bfd.mode5.txt b/test/unit/data/small_bfd.mode5.txt new file mode 100644 index 00000000..9fe7ab29 --- /dev/null +++ b/test/unit/data/small_bfd.mode5.txt @@ -0,0 +1,240 @@ +>O31912 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A163VT74_9BACL +-----------IDPAKWGISTDGTNSRATTDGLNAALADAKSKGFGEVYLPKGKYLIDAVCKTN-HSPEIGGGIRVPSNLKLTLDSEAELKVEPNGSYGYSCIFLDNVHNVTITGGIVTGDRNEHDYS--NKTKPTHEWGFGINVRGGTNITIDNVRIKDCSGDCIYVNAIGMINYGTVPYTPPQKVMIQNCTLDGSRRNNISISACDGVVIRNNLILNAGIQTdagpgfkskIGPGFGIDIEGYGEGDIDYETPLNIVIQGNQFRGNRVYSVGNFNGYGVVIEGNFADNTLSYGNGTDTVIANNVLIRT-DRQRTGIDGQGVSQGLEANHVTIMGNIVKGFGSGMDIRGKDVVVTGNALSHlgEAGVGIAAFAAENVWIANNSVHRTKGTPYRIASCKDVQLVNNKAHGSDKT-AIEANASSQVILRGNVVRDCSGGIkvtnissEASNSEVVvesnHIDLTEY--KGKtAYAISFDSKSEVTLKGNRIPGPRNTAIYGEGGIgKRAKIADNEIADANSFTAmIQIVGGAKHEIVGNNVTFNKSSNGGVGIYLKDAKDSIVAKNTVYSNSEYALTHSIATKESTGTKVLNN------------------- +>A0A090ZKM7_PAEMA +---------YVIDPAQWGIKTDGTEAVKTTEGLNKAIAHAKSAGYNEAFIPKGTYLIQGVGTTFPNTPEKGGGIVVPSHMKLTLDHEAELKVQPNAERGYSCIYLRKVQNVTISGGIITGDLDQHDFSKL--PKSTYEWGFGIYVHGGKNITIENMKIRKCIGDCIFLGSVGLLGVDPDYDKPEK-VAIRNCSLDGARRNNISITAADGVFVENNVITNAG--TVkgtKPWAGIDIEGYGEGAIDYEEPRRVVVRGNVFRGNAEVSVLNFNGYGVIIEGNHADNTFSYGNGTDTVISNNVMVRTDGSK-VAIAAQQVSNGYDGNNVTIVGNIIKGFSSGIDARGKDVVVTGNTVShlgNTGGTGIGVWDAENVLVADNAVHRCAGLPYKVDNSNDVQFLNNKAL-HSERFGLELDKSTNVVLRGNSFGQCNGGIsiknWGTKGTSVFAEGNYIdcaSYTGKqtnNYAISFDKNSDVTLKENYIFGSRSVAIYGESSAGKIvKIADNEISDITGNSAIQIKGGQRAEIVGNRITFKRKDDAAYGISLaDNAEDAIIAQNTIYSNNGKSIPNAIVTESSKRTKVLNNLLINGKMLLNKDDTNI--- +>C2WEL3_BACCE +---------YLIELSRWGI--INDGSKETEKEINNALQWAYDNGINRCILSSGTYLINAVGPPNDLQ---AGGIKIPDNMTLDLWHDTVLKVKANDSYSYSCIYLYNKNNIKIRGGTIQGDRYHHDFSTAPTGKLTHEWGRGINIIGCSNITIDNMNIKECTGDAIDVLSIGLMN--TQVYIPSSNITIRNCTLDKSRRNNLSLEGCDGVLVENNVITNAGiDDGTAPRFGIDIEGYGEGATDYVVPLNIVIKNNKFEGNVTTSICNFNGYNVIIEGNISDNTISYAYGTQTIIS-NNIFKRVDLTTKAISSIGTAQGLDFNNTTITGNIITGFDTALDIRGKNVTVSSNIIYDVK-IGISLFQAESILVQGNLIKKATFGKaIIINTCTNIKCTENQLK-DIGMLCIELNNSSAVTINQNDIFNSKQGIRISKSNAVlqgnSIDLNTF--NSPSYNIDFDATSNVLIINNLLKNCSSFAInlsNGSASSKS-RIIKNIIENFTAISAINLSGG-RHELIDNILIANKNIAGGYGINLHSCNQSTVLRNHIFSSSIYNLSTPIKTNTSTNTKIIEN------------------- +>A0A238U6X6_9FLAO +-------------------------------------------------------------------------ILLPSNFHLSLHEETVFRVQPNAFPWYSLMTIDKKENVKISGGNFIGDRYEHDYvPFFDrhgLKRSTHEWGVLLLVRGSENINIDNITLKSSIADGLITGSEGHRIYPETVW--NKKVSLTNSIVSDNRRNNISITDGEDILIEGNEILDAGiGETlkdndgntiyssagVAPRFGLDVEpfvGYDdfsfESRKTYEWVENVIIRNNIFKGNEAGSIIVYTGDNVLIDGNFSDHVIAQN-----NTSGSKIINNTlEARDDVRGRIGISTSDyrkfidfdggtlkqyaTGN--DVKNNTIRNFFGGYNIRGNNAEVSGNTVEGATVCLL------------------------INKAENIKVHDNTyTSGAIASKAIRLTDyANNIEIYNEKFT-LSNGFYLE-SIDFNMPNDDFHLN-------------------------------------------------------------------------------------------------------------------------------------------- +>LauGreSBDMM110SN_4_FD.fasta_scaffold226965_1 +-------------------------------------------------------------------------IHLPSDFHFKMSKSTFLRVQPNFWPRGVLLSVYEQKNTLVSGGNLIGDRYTHNYAPIKDElgiaRDTHEWPVLLSIAGCKDVIFEKIYMTDSTGDAcVTGATNGSRDIGGADKKFNQNVIIRGCVMNASRRNNISITDGEDIFITNCIIQNGGnGDTVkdasgnkivtsagtAPRAGIDIEpfrGYNPDGsfRNFEIVKRVTISGCTFKNNRVASIIDYSGINTTIKNNTSDHGFFASFSTGTKFLYNTFKASAINKDKVAIVTGnwiINNTQLSKNNEVTGNKIEGFRVGITTQGDEGNVSNNTI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_4058357 +-------------------------------------------------------------------------IKVPSNTHLLMSDNTFIRVQPSNNPFSRLLMTYKAQNVLIEGGNLVGDRYLHDYSnvtdEIGVSRATHGYGSLINIAGSQHVTVDNVNIYEGEGDGVLIQISAIRNKDGSIKAgemESSNVVIKNSLIDKCRRNNFSIIDANGVLIENNVISNAGGEhesgqayaGTAPEVGIDLEAYRERRSdgslyEYERVTNVTIRNNEFVGNDVADVIVYTASFVDIIGNTFDNRVGVHAGHDVKIANNEF--TAGERittqiAVSFDNFIVNETEhlTYN-IDVTGNTISGYDTAMKVGTQNVTVSENKIYDFVTGINITDI-ENAQISNNTLE------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1V5WUJ2_9DELT +---------YVVDTDKWNIPTDGSDPERTSAGLSEALAWAVDNGFGTVRLPAGAYVVG-----REINSMFIEGVVVPGPLRLDFEPGAIIQMKPNDHPFYCILDIADASDVWIRGGTVLGDRESHQY----VGESTHEFGTAVCVgsrGGSERILIENMSLAEATGDGITI-----NDAPG----SSRDITIRGNDIHHHRRQGISIISGSAIVIEDNEIHHIAG--TAPQFGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A090II36_9GAMM +--LLNSSIhiggdvhlsnaNFVFDNQRWGVvegIVNNEQAKENTRLFQYALNQAHNVHANVFRINKfdASFWVGNYKKFN--STEL-SGITLPSNIKLSMRHDTILRTQANGYARYALLGLYNADNVTIEGGVLIGDRDTHDYK--DPQSPKPYWGHLMKIGGSRNVTIKGVTFKNATADGLSIHSLGTYKRTGSIET--KNILVTDCLFDNNRRLGTAITSGSEIIVEHNTYLNSGqpseaSESVSPAWAIDIEGGYKDHEYLERPYNITIRNNIERNSYRGAFIGAIGDGITIENNNTENTIALG-SVFNSKAFNNTITRDLNKEY-LNPNGLSVAYDGEKMFYPTEEVVGnnevynnklIRARMYISGSGNSIFNNSISN-SLTGITIQKAKNAEIYNNSVHSNveNSIGLSARDSiNNVNVYDN--DFNIEGLAIRFISINE-KLGHENFS---------------MYLNNNRFTSSGY----NKAASVSRSRNVYFNENNFSNIGFI-MYtsdNIQLIGNRV-ETKTRIGLQIEEGNEQIKLHDNLVIHPEKKK---CIRNLSEQIPDIKNNV-------------------------------------------- +>SRR5690625_80756 +---------YELELARWNVSNNGTRPHETTKGINEALNWAKENGYTSLLIPDGTYSIAKGNAENDRHAR----INMLSDMTFLMSNNTILQKEPNGFEEYSVLHVGAgVKNVVIQGGTLIGDREDHNYSgkSGDWSSGTHEWGHGISIVGGENITVDGVKIKDFTGDGIYI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_9554453 +---------YLVELDRWGISADGTNAEATTDGINEAIRWAQGEGYGRVRLPAGTYLIG-----KRLYDHYTGGIELVDDVALMMDDETVLQIVPNDTWAYCGIAMSGVRNAGVYGGTIRGDRDEHTYG----GSMTHEDGHCICIgHESELVEIDGVTMEDPTGDGVAIVAEGGDG------SSCKHITIKNSEIARGRRQGISIVGGTNVWIENNEIHHIEG--TAPQFGIDIESLNFTSR------DIVIRNNRFHHN-RGGDFENADGKnVWFEENHLD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>APAga8741243855_1050100.scaffolds.fasta_scaffold124648_1 +---------YTIDNEQFGIYSNNTHARTTTDGINEALNWAKSHGYTKVRFAAGTYLIQC--TWNNRYCAPDDGILVPSGMTLDLG-TATFRMEANNYPAYTIFGIVNKSNVTITGGTLIGDLGSHTYSSV-SGSSSHEWGFGICISASKNVVIDDVTIKNMTGDGVILeGSYAALSNGGRV---CSNIKVTDCTISNCRRQGISVIGAtDSELARNRIYGIKGTD---PQYGIDVEtefDYVVDDLKIHH---NNISDC-----SGGAINCNKGENYDVYSNTVtgDNIIA-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2G5GBI8_9FLAO +------------------------------------------------------FVIDKLDAYFKIDGPLSEGapvdlaIQIPSNFTFRMSENTHLRVQPNATDKCTLLSVYLnSDNAVIEGGNLYGDRDEHDYSDGIND---HGWGHLFTSRGSTNVTVRNVTMIDAAGDALKLEGEGHAVNPD--YAPTRNFLATGCKFIRSRRNNLSITAADGVVIEDCDFIDAGIHTdksqgTIPGFALDIEALKPN----ELSENIIIRNNRETGSRRGGFLVAIGDKVTFEGNVINSAINLQSARNCIVRNNIVTAQSDiAKEYGAGII-TGRSDRGNLVysnTIYNNTVNGFSTGISISNFDMKVYGNTINNCnrgmsigpvqnseiyentiiSNVDKSAGISMGASLNNVVVRNNDVNVMRygavFANVNNTDESGNytltfKGNNIVSGSSTPINSSHGIELIENTFNNAYEFYNCSNLNII------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A167HAM4_9BURK +---------------RWGVASNASNATATTDGMQAAIDWASSQGIGQFRVPAGEYLLGKIQTYN-----YAGGIKLPSNMALVLEPGAVLRMVPNDRWNYCVVTINGKKNVSVSGGTIVGDRYNHTYTPSSSGGTAHDEGHAICIEGSSQyVEVQGVYITQANGDGILIV--------GKAPSTPQDITITGNNFDTNRRQGISIVGGARVLIEGNQIHHTKG--TSPQFGIDIEPLGGylvrdviiRGNNFHHNRGGDVVNTRgfniliegnTMHQGEASTTGGDDGRT-----YIDGPIVFWPEADQTIRNNNI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A1I1IH73_9FLAO +-------------------------------------------------------------------------INVPSDFHLIMTDNTHLRQQPNANKRATLLAAYLISNTIIEGGNLHGDRDTHDYSDTSTSQ---EWGHCIRVGASKNVIIKNMNIYDAGGDGIDIHAYGHAYNSHYTYTENLLITNNK--IYRSRRNGISITDGRNIVIEDNEFIDSGVSTslsggVAPGWAIDVEAVRNSGVIFEIAEDILIKNNVERGSKYGGFIIHTGDRVTIDGNTMENSIAYAGTIGSVIKNNNLKSNSETALRGQTTGIIAQNKASSKdNSVYGNTVYGYPIGIKVGDTNLNVYNN---NILECAVG---------------------ISLNTSKDSRIYGNTIKSTT---------ANSRGISNHThdyISNLiIGSGLDENNESAKSNVIDVVgnaIVFNGIKEIENSDTHSIIIKNNIIE--NGANLWLIDINNFEMHDNVI----------------------------------------------------------------------------------------------- +>A0A238U509_9FLAO +--LLNNSLTIQGDiqltkneFDfipsKWGIvEGVTTNEISRT---NRDIL---ENNMTFIKsLGASIFKIDKMDAfFNVDEPDIlpsEAAINVPSDFTLKMTNNTHLRMQPNAAIRPTLLATFTASNVTIDGGVLHGDRDSHDYTTINS---THEWGHLLRITGTKNSVFKNIRFEDATGDAIDVHAYGHSFDPH--YTYCDNVLITNNIMLRSRRNHISITDGRNITVEKNDFIDASIHTnkstgIAPGFAIDVEAV-----RHGNPRGISeIAEDIFIKNNTengsrvGAVTVHTGDRVTIEGNKFENSISYSTSIGTIIRNNEIiattyknINNG----TAIVAGRADRYDDNYNGKVYGNTIENYAIGMTVSNKDLEVYANKITN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A0P0CI41_9FLAO +-----------------------------------------EGSFELVKsLGVSTFIIDAMDAYFKVDDENFKGyaytyaINPPSNFTLKMSENTHLRTQPTNFSNYALISVRDVENVVIDGGNLYGERDEHDYS----SGGSHEFGMCLTVSGSKDVTIKNMTITDALGDGIIIDNIG-HTYDSF-YTYTDNLLIQNNKIIRSRRNGISIVEGKNIVIDGNELVDTGITTskssgAAPMWAIDIEPVWENGIKYQIVEYVTIKNNIERGSEKGGFINARGWYITYENNTMENTIAIGETVGSIVRNNIFKNPGKNSNVAIaagmnDPLGYGN-ERNYDNEVYGNTITGFPKGIELQDPGIDLHHNTM------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>J8DZ85_BACCE +--MIEKVNIYVIELDKWNIKKDGTDAVNTTKGINKALLWAKENDYDVCKLPAGNYLVDK-----------DSNIEMVSDMTLDLF-GCTIRKETNGYQGYSIVRIFRQKNATILGGTIEGDKDTHDYSTIP---GTHEWGIGIDVSGlNRNIKIDSVKIKNTTGYGVRTGTeYGHLSW---VYTTDlESGTfsndgVLKADVNFTRSNkywriteypQIQENGYFSIMGNGYGFygsTKDGGEVNLDRVPITIYFFDESNKFLGKITKRTFDNIYYSSFPKGT----SKFKIGFRFNYNNiNALSMTIRSMTYTKGINVIN---TDIYGCRALGIAITGAQNMLV---DNCEIYGIGGINPGYAIDIED-----------GYNINQNIIIRNNYIHDNNNGAIVVVSARNVLLESNKFYG-----SVFLGGSRGENYLSR--HNLYncsfgtGSTNAGGGDAATITFrDDYMLEGQLYmegNAFYDNvcfDNMTFVLQSDTF---------------------------------------------------------------------------------------------------------------------- +>X4ZGB9_9BACL +---------YLIELARWGIYNDGTHPVETVKGINNALVWARQKGITATTLPAGTYLIDKASRIN-----------MVGDMLFDLPMDAVLQKETNGKERYDVMYVGYgANNVTLRGGTYLGDKLTHDYSQRDPyNTGTHEGGYGIFVEGAKNTTIDGVKAMNFTGDGLVLGGFGTM---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1A5YEI2_9BACL +---------HMIDLKRWGISSNGTKPVQTTQGINKALQWAAKSKITAVTLPPGTYLIDK----NSR-------INMVGNMLFQLSDDTILKKQENGKEHYELMFIGYgANNVTLRGGTYLGDKDSHDYSKKDNPHTpgTHERGYGITVLGANNITIEGVKGTHFTGDGLIIGAH------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2B8JB68_BACME +--------------EKWTIHNDGTYPIETTSGFNNALAWASAQGIHTFKVPAGIYLIK-----KGVDYDATARINMVSDMTFIADNKAIFQKETNGLTGYSVMYIGpQVKNAIIKGGVYKGEKDTHDYSI----SSTHEWGYGVLVEGGENIIVDDIEAYNFTGDGlligntirkgtyinssilesggldengnptnetgrirtvgrtqtnfddaiykelnsfyLWVPTgltknqydvyfydkdgkllerklnvnmwKGEVNIPkgadyfktvlyadstsgASVYryaiDNSKSVTVKNSKMHDNRRQGITVGGGYGVLLENNEIYNIRG--IAPQSGIDVEqGYGINGnvtirnnNVHDNVYGVILYDGIGATVEENQIKNHSYPGLVVQEEYKDALVQNNYfeNSGMSIK---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1M6AGX2_9FLAO +-------------------------------------------------------------TTNQNFYPSREAINVPSDFTLRMTDNTNLRVQPNSRKNYVLLAVRDASNVRVEGGNLIGDRLEHD---DNSQPGPHAFGFVLMIHGGSNVDLVGVRTILGTGDGIDVNSIGFTFEAG--YIPSNNIRITNCIMDSNRRNNMSITDGFNIVVDGCQFLNAGIDMPGspgmaPGVAMDVEAFrgkddAGNFILYERAYDLTFRN-NFEKGSKfGSFVVAIGEDVTIENNTTEDGIAIGAGHGIKIIGNTLIAAADDNiGAGITTGHPNSTDTYDNV-IANNRIIGHNIGIAAYQRDMKIYGNVIE------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>GraSoiStandDraft_43_1057313.scaffolds.fasta_scaffold3393195_1 +-----------IDNAYWGIVTETNTEqigIANMENINRAIKTAHENGIYKIKLAKATYWFDA--TSDKTTPSIG----LLSNMQFNL-XXAXLRVMPNNLTHHYFIYIESAENVKIFNGTITGDRYEHGY--VPATYPTHEWCHGLRVGSNSSNYCKNIEIYDLVVQE--------FTGDGINVSWSKNVTIRNTEVSNARRNGITIgSNTDETYIYDNYIHDTHG--VSPACGIDLEKAAGDGPKNIVIRNNRIYDCINPETGaeQGQAMAISGGsyQVTVRDNDIRGVIGFAYAEKILIENNRI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A229GVH8_9GAMM +---------------------------DDTAAIQKAIDAVAAKGGGIVEIPAGTYMINGAATsvLGPGDVPRTSGLQVKSNVIIRMADDTVMQVIPNGEKHYDIFNIYNAENVAIMGGTLRGDRHSH---LNDQG----EWGSGIKIASAKNVVIEKVIAREFWGDAVHISDSG-----SLPRTPSQNVTIYQLAADGNRRQGISITSADKVLIEDSAFKNTGGQgGTPPMAGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A098MBD8_9BACL +---------HLIELSRWGIYNDGTHPVETTKGINNALTWAYQQGITATTLTPGTYLIDKASQINM----------VP-NMLFDLTMEVVLQKETNDKESYQIVSLDYGDnNVTLRGGTYIGDRLTHDYSKKDhvGSAGTHEFGYGIIARGVKNLVIDRVKTTHFTGDGIILAGHGTM---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2A2AT09_9BURK +-----------------------------------------------VWIPAGTYMIDaTVNACGGWGQE-RCGLQMRSGVTVHMSQQAVLKAMPNGSRHYNIFHFNDVENAHVLGGQLQGERYAH---RIPTDGRLGEWGAGLVMRGARHAAIENVTAREFWGDGF--------------YVGGSSQNVKFCAVvaDKNRRQGMSITDVDTIVVQDSVFKNTHG--TPPQDGIDIEPWGqENEPIREHVKNVTIRRSQFINNagrGIGMVTTHPGqiENVVLEGNtFIDNSIGLGLgnrSWKTRITGNRIIN----SQY--LNIGLGPLAT--FITVTDNAVTG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_2407419 +-----------------------------------AAIQAAINSLPsaggTVTIPAGTYLIDTSKKIN-----------LKSNMLLKLDPNAILKAKSCSLIRHYLVYVNGKTNVEIAGGQLVGDRDGHNY----VGSSTHEWGHGIQILGSTKVTVRDLRVSKCTGDGVCIGG------------GASDVVIGNIIATNNRRQGLSITNCTNIKVYDSEFSYSKG--TSPECGIDIEpddGHSlstvliqncrmNNNGKYgmniwKRVSGVTITQCTLERN--GSLGLGTNGCSGIK--FTNNIVRYNSATGV------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1719318_174446 +---------YKLNLEDWDIPNNGHEPRKTTENLQKAIDWAHGNAYTKVLLPRGHFLLGIeaaakypwgwTNGKRKEDNFSMRGLSMHSNTEFILDSAATLEMVSNDKVMYCIICIEDVTDVIIRGGTLKGDRETHTYTP-HHNRTTHEWGHGILISDRvHRILVTNMEIKDVTGDGVYVKSEKK--------SIGSDIIIKNNDIHNARRQGVSIVGGLRVKIEDNEIHHIKG--TSPQFGVDIEG------PWTVTKDVIIHRNNFHDNRGGDVVNFDGKNVFITENKMIESDSYSYT---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>APHig6443718053_1056840.scaffolds.fasta_scaffold2008830_1 +-------IKYYTP-QQFGAVANDTG--DDTVAFNRALqAAASSSSTDTVFVPAGTYMIKADGG--------DGGVQVLSKTKLKMDPGAVLQVITNAERGYNCVRTNGVTDAEISGGTICGDRTTHTGT-------SGEWGHGIGIYDSTDVTISNVVVKNCWGDGVYI---GTAN-DNSTTAKSRQISLSGVTTDNNRRNGLSVVAADGVTVDGCLFVNTNG--TDPQAGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_7665223 +---------------------------DVTSQLQTVLTNIAKNGGGIVYLPKGNYMIKAtssdpswTNPQSLLTPAKLEGLQVGSNTTILLDKDASLSVIPNNFWNYLVLNIQGADNVNILGGTLNGDRLSHDMSNPNwtwnngkgfNSPYYGEWGNGLSIQSSNNTLVSGVKFKNFWGDGISLFPDKDQAEAGAL-SQAKNVHITGCTFDYNRRQGISVGHANNVEIDHSLFENT--DGTGPAAGIDLE---PGGGSTEQVTNVKIHDNVFLNNNNAGLTAYAAPKSKV--------------SDVHVYNNTFINNG-------------AWMPG---QITFNN-----------AEYIEIDHNKFDNDD--ASRFHSSWIVNTANDNIHDN-----YGRNSSirIAKEAHGEGKVTNNYVSSIMIENTGYDVANNHLPN-------------EISSTDLGTMGANWNYQNDVDYPGLATNEKVtfhdFNSRGKALNVTANPDNTVLNQSDPSNCQADISFDIDG---------------------------------------------------------------------------------- +>SRR5699024_10005537 +-------------------NAKGDGVTDDTNSINEAIDYAVENNINTVYFPSGIYMIkaDAEEIIPNGSK---GGIHLKSNITLKLDDNAILQAISNSAEGYNIIRAKESNNIKVIGGTIKGERSNHSGS-------EGEWGHGIHLKGCSNVYIQS-NIIDCWGDGIYVG--------GDVSTddskPTKNLIDENTVCDNNRRQGISIVSGKHIRLLNSDFINTNG-TL-PESGIDIE------PSHDRHIvrDVKVIDCNFNNNaGTGFLIDGKSG--SVEDIYVNGI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5207342_2131982 +---------------------------DDTRAFQDAIDAAKGG---IVIVPAGDYLIDPLHS-----------VRVRSGTQLRMDRNARLRAIPNAAPRAYVLLLQGVEDITISGGQILGDRKEH----LGT---TGEWGHGIAIYGASNVKVRDVRISGCWGDGISIGS--TKAGKGGVMRPSTDIEIANVASLGNRRQGLSIGRSRRVYVHDCEFSDTGG--TPPSAGIDVE--PDAG---DIAQDVRIERCILRRNrGPGiqvwkRATSVAIRDCTIEDNRNAGVLAVG-AIDLAIERNRIRGNG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_3757948 +-------------------------------------IQAAINSLPstggTVFVPAGTYLVDAVRS-----------VKLRSQMHLKLDPGAKLVAKPTSSESYNVVFADVAHDVEISGGQIIGERHQHKGTV-------GEGGHCIRIRGCERVTVRDIRLSDGWGDGITV---GPRPNRRKRFTYSQDVAIANIICDGNRRNGLSIGNVIGIKVYDCEFNNTNG--TAPQCGIDV----EPSPDFDgsgHCDDVHIENCRMSGNGAygMNVWKNTSNlvitKNTIEGNKTCGLVTRG-MTSSSITGNTI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>R6FQI5_9CLOT +---------YGVDIQKFNINNNGLNPIETSKGINDALNYAAKNKYDKITFPKGEYCI------SEENP-----ITMVSNLIVDLN-GATFKINDNGLQHYTVIDFSNCSNSQLINGIILGDRETHDYKTIE---GSHEWTCGIVFNNCDNCILDNVTISSFPG-------YGISSSLGENLS-DLIIGVTKENLSIGNINDKGkLNNKKGTIrtIDPLNISNVGGEfELGYNKGYMGYPYMQSKEYLSYFYDenmkfiSKVDNCKQYK------------KVLIPDNakYVHFVFKQDY-----------VPERGDTDFNGTTVFLTNYSSPNNITIKNCLIEKNKsLGMGIcGGYNWNIENNMFKenggGAPGYAIdledGWEYMDSFLFKNNKFigNNNDIVSCAGDN---IIFENNSFTSTVYMWG----RTTNYKFLNNSFSNIAMNINYEYSTDTECSGNTYnncriAITSK------NKDAEFNINNENIIDthvntmPENVSIIDskitADNIDNIRIYGN-FKDCH----ISKVTGSLVNFRGEKCKINNSN----------------------------------------------------------------- +>SRR4249919_2030177 +-------------------------------------------------VPAGRYLIDAVKS-----------VKLPSNRKLKMHPDAILVAKANNAEGYNVLLVERVDNVQIVGGQIVGERDKH----IGT---TGEGGMGIRFRGATNSSVTDTIVSNFWGDGI-VAG----PYKGSKYIPSTDITLKNVTMSGNRRNGLSVGNVVRFLAEDCKVLDNGNDPDGtgpivggtsPFCGVDVE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1S1V829_9FIRM +---------YYAD------AAFTKPATDATQAINSAVKHASQNGIQKVVIPSGNYLIKAEGvsaTGIEGDYAKTGGILLQSNMTLEMSSNAVLVTNTVNKPGYSLITVNNKSNVKIVGGKLVGDKDTH-------PANTHNACYGISiINGSKNIYVDGTEITKMEDDGIMITDYAIDQSGG---TRSSDIEIRNVKSHNNGRQGLTI--ATGSNIKILNSEFSNQTKHEPKSGIDIE-----IESYDHvgVKNVEISGNKFEGNAFSGVlfsnmfndrpnsmsenikingntingSRHgilAEGKSNGLDMSNNNITVNNYnvgqssvavgtlsaeSSGVVISGNNIISD-DSKAH--TSMGVYSTTPG--VSINGNNLVGQNVGMMLSGGGEQIVGNKIskvlatgihisgsnqnisENEISVSGAAHLssdsyhnviyaayAENLAIKNNNFHDMKSYGINlaegVRNT---EVSGNTMKNIgTEAFPNKnsflhiASENTGINVTGNTFDrGAYPTLYLGISYANSVKgANSFTnneiigFSSYGYGM-------------------------------------------------------------------------------------------------------------------------------------- +>A0A1M5UZK5_9CLOT +---------YTIELDKFGIKNDATFAVETSKGINDALQYAKEKGYEKIVFPKGEYLISELNPV------------VIDLKNVVIDlNQATFQINTNGLEKYSIIQIvDGAENIRLTNGIIRGDKDTHDYKTIKT---PHEWGCGIVFKGGKDLEMDNITVTNVTGYGIYTESGTNSNRFDAVYT-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5687768_13918870 +--------------------------------------------------------------------------------------------------------------VSIRGGKIVGERGAHHGT-------TGEWGMGVRLAGCHDVRIQGVQITDCWGDGIYVGANGVGN-------ESRRIKITECILRNNRRQGLSITGCIGALIRDCEFTDTNG-TL-PASGIDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A250E5Q6_9FLAO +---------------------------DDTEAIQNAINEASKKGGGVVYIPEGTYLIDAKQSLVIRS---NVTLQLAANAILEAKANTILEAKANTSERYDILYIKNVENVKVVGGTIKGDRNIH-------IGNRGEWGMGIGIYDGKNIVIENVSVRDCWGDGIYI---------GKNRNRSENIILEKVKSVNNRRQGVSITAAHKVTINHCVFSQTNG--IPPQAGVDIE-----PNAADTVSNVVIKNSIFDSNENSGILIYTGAERS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_21041421 +--------------------ADNTGSVSTQSAINAAIALQNARGGGVVYVPRGTYLIDT-------NYLTGGSVRVLSNVTLHLDPGAVLQAVPTSNGQGAIVWAYNAENIIIQGGYIRGERDGH----IGTDQP--DGNHGISIFSCDNVTVKNVRVSHCWGDGMYIRNDTGGNNTG--DTLSTQIRVLDSSFFNNRRTGLACVAVDGLTISKCYF--YGNTGANPYAGLNLEPNSDGWVR-----NCVVSDC-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1H9W652_BUTFI +---------------------------------------ASNGGLNTIYLPAGVYNITDIGNYDH-------GIELKSNVNLIMDKNAVLKVSGMPYGDYEIFSMRYLSNVTIAGGQLVGERYSHSgyYG---------ESGHGIAMHGCSNITITNMCISANWGDGIYFGTQAVWLGSGQGYFGNTNVTISGCDIFDNRRNSISFTDADYITVDRCNLRDSHG--TAPQCCVYFEPNGDSSDK-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR2546423_4745973 +-----------INVRDWG--ALGDGISDDTPAFAAALATLADRG-GTLSVPDGDYRIDPLKS-----------VRLTDNVALNLSRDAILRAIPVTARNSAVVLVERARNVRIIGGTIIGERDGH----LGVGG---EGGMGIWVSASSNVRIERVTALDCWGDGFYIAgwsGRGSYDANSLHESHSDNVTVSRCIARNNRRQGLSVVGCIGGLIERCGFTDTNG--TAPQSGIDIEPQG----------NWTVSNVTV----RNCVTARNAGWGIL---VCGNDIYNASVSDILIEGNR------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6185503_5510564 +-----------------------------------------------VDVPAGRYRIDPVRSIHLADSiamEMASGAVLAA-LPVAQGNSAVIRL--DGIQGAS-----------IRGGMIIGERDGH----LGT---AGEWGMGIQIMGGSTISVEGVRIEGCWGDGIYVG--------GRSGVEATHITIRRCVVTNNRRQGMSMTGCRDSLVEGCTFASTHG--TAPQAGIDLEpnggfvvegvtirgctvegnhGYGivLSGGREQHVQTITLDDNRVADNG-----FHGIGVVS--------------SVDCSVRGNTVEHNG---RDGVQIAGSSRVRlTGNTIRDNSRRTAGVWDNVIV--QSLSTDNTVANN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1E7DPH2_9BACI +-----------INITDYGANADDSK--DDTSSIQAAIDAAAGKN-GIVLIPAGTFLINT-------DPET-GSLNVKDNIEINMDEKTILKSIPNGLPIYRMLTIYNRENVKITGGTLIGDRYKHEGT-------EGEFGHGIYIGGnSSEITISNVRAQDFWGDGFFVEGNASQeTYP-------SSITIDNVESHNNRRQGISITAGKQIVVKNSIFSGTNG--TPPAAGIDLE--------RDPPYSLPLEEVELLNN-----------EVFNNEGY---GISFIYASNSSAQKNIVKNnkKGGIYIGGGVEQGIAKNNT-----VDDNFISENGLGIFVNfSTQNNISNNVIEKSKKDGIVliNHVGQN-RLVKNLVRDNQGNGLYIwgglHDQSGIVVQQNKiSKNSKAGIAVlNVLDATITD--NDLLDNAGAGLHREEAKESTIERN------------------------------------------------------------------------------------------------------------------------------------------------- +>F3B2U2_9FIRM +---------------------------DDTAAIQRAIDAVSAAGGGIVDIPAGNYMI---NTLHQTGHSYeRAGLVLKSNIIVRMANGAVLRAIPNGERSYQIFSITHVDNVHIMGGKLIGDRDTHIGNLGQT-------GYGVRITDATNVVIEDLYAGEFWGDGVFLG------------EDSRNITLYRVICDHNRRQGMSIVGGHNVKILESEFKRS--DGTPPKSGIDIEPEG------DHPIvsGVEIRNCLFEGSSTGFVVSNQySNSVAENIIFADNI----------VRGNKT---------AVNLVGIQSGEvTGNTIyhdqSITEN------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A177L0L1_9BACI +--------------------------IDDTDRIQKTIDFVNKKGGGVVTFPKGIYLIDA---------EI--SLKLKDNITLKFEKGAILKALPNNAESYEIVKIHDVENVSLLGDiTIIGERKEH-------IGKTGEWGFGISIRGAENITIENPFIKDCWGDGIYIGATTKKKY-------SKRVTIINPLIENNRRQGISVISAVDLTIISPKLLNTNG--TSPQGGIDFEPNSEN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A150W909_9BACL +--------------------ATGNGEVDDTIAIQNAIDFAYSNGNKTVFFSKGIYLVDSSTSL-----------VVKDGIVLKFENEAILKAIPNALERSEVIRIHDVKNVKILGyPEIIGERDEHLGS-------TGEWGFGVSIRGAENIYIENAKISNFWGDGIYIGSTAKKNY-------NINIEINNVELTNNRRQGISIISVENLLIKDATITNTNG--TSPQCGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1G2XYR5_9BACT +--------------------------------------------------PSAVYNIDADGTGDQ-----SAGLKLPSDVNVAFEEGSKLKVIPNSSTVYSVITITGKNNISLSGACIEGDRNFHTGT-------TGEWGFGISISNSQNITIKDVNVYDCWGDGIYIC------------SVSDRVTVRDSIFNHNRRNGCSIISAKNVLFENCVFSNS--DGTSPYKGVDIEPNYEsdilqnivfnNCRSYNnlakgfspafdgaliNPVSITFSNCSSDGDGTGfgidAGPRNTLGTITFRDCTSTNAVENGFSciaanINTVIDGLYIVNPG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6478735_8854003 +-----------VDVREFG--AKGDGRADDTDAFEEAIEALPAGG--ILDVPDGDYMIDTLRSIRLRD---GIHLRLARNARLIAQPNAA----PRSY----VILLRNVRDIRITGGAIVGDRDRH----LGLDG---EWGHGIAIYSVRNLVISGIHISKCWGDGMSIG--GKSAQKGQPATPSMDIEIANVTSVGNRRQGLSIGRSRRVWVHDSEFSGTGG--TPPQAGIDVEpdkgdivqgvriercvirgNRGPGIQVWKDTHDVSISDCTIEDNRNAGILAVDATDVTIRDNRIRDNTQVGIalrkgTRQVSISGN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1C7EEP3_9BACL +--------------------SYGNDKMDDTQFIQNAIDFQSSKGGGVVYFNKGEYLIDSTKSITLRD-----------NITLEFEQGAILKAIPNSAERYEIVKIHNVKNVNITGQvSIVGDRSEHTSSL-------GEWGVGISIRGAQDINIENVSISDSWGDGIYIGNTSKKNY-------SENIKINNSNFDNNRRQGITVVSVKKLEIINATITNTNG--ISPQSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1I2HG07_9BACL +-----------------------------------ARINAAINSLPasggTVYIPEGTYMI---NTGNPYNPVTNATcISLKNNITIKMTENTVLKAITNAYNNYAIFLVRAVSNVTIEGGILQGERYTH------TGPTAGQVGVGVWLEGATNVTIRDVTCKEFWGDGIYTLYHSTLG-------NTKKVTVENVSFIDNRRQGISICANENFRVIGCSFEttqgtdPAAGIDIEPELGgtvrdVTITGNVFKGNKIGiqalGDASATITGNVFEGNTMwGIYLASSSRYYSVTGNIVYASGNYGIyvntSTDNVISGNVVYNNG--------SHGIYLLNNADRNVITDNKVYGNS------GEGI----NVYKSFDNII-----------------------------NDNNVTNNKGRG----IFIAVSTDNSING-NTSSSNALSGIYLWNSKYNLVDSNRCSKNGQ-HGIFVKGDAANDSLSNSI--------------SNNQCKENSQTTNQGYQNIFLSSGAQGANTINNVQGNMCRAGGlankpqYGILIDaNTSETLLKNNDTRGGGAK-------------------------------------- +>M2U1I2_9SPHN +--------------------------------------------------------LDVVSPTNGRR-----GLVIPSGSHWVMHPEMRIRALPNASSHYEILNILDEEDIVIegNGARLIGER--------DTHRGAEgEWGFGLSVRGARNVLVENLIAEDCWGDGFYIGS-GRRKY-------SQDILFRNTKAIRARRNGLSLISVRGFLSEDHESAHTFGSA--PQWGVDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690349_1434838 +--------------DVTSMGALGNGVHDDTAAFQSA-IDALPADGGVIDVPPGTYMIDATHTsCPGRGTALQCGLILRSHVALSMDVGAVLRVIPNDQERYYAIYVRGLSDVEIVGGRLVGDRTTH----LGT---TGEHGYGIAIAGSSNVRVRWTEVSNFWGDGFIVSRTGGDTNP----TYSRYVTLDHVKSSNNRRQGLtVAGGVQYLLVQYSTFRDSNG--TAPEAGVDFE--------PDEPTVAPVSDIRLYDN--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_575702 +----------------------------------------------------GTYIING--ELEGHTYESVGGIILHDNIILQFAEGAILKVMPSESEFYSDITLKDCNNVSVLGATIYGDRSEH-------RGVTGEWGHGVKVIRGENINIKNVRVSDCWGD-------------GVYFRDTKNVTVEYVISDNNRRQGMSIVGGENIYVRSSVFKNTNG--TQPETGVDI----EPNHDYQVVKNISFNDCSFHDNVSKGLMLFTNGGT-----FEDIVVN-----NCSFSGN-----------GAESFRVSGRGNHCNIKITNSTLEHMALGTSA---------THVLNAS--------ADNVIITNNYID-----KIVLNNTSNSIISKN-----IIIENIVLVDSNtNIRIENNIFNDasdidrirlLYDEVYDDASKYIYITNN--TISGGKRGVF--VQSTEFLSLYSTINIKNNMFIGLTE---------------------------------------------------------------------------------------------------------- +>SRR3546814_95907 +-------------------------------------IYALPSTGGTVVVPDGTYMIDAVRK-----------VRLRSRMHLKLSSGAKLVAKTNSSPRYYVLDDGNASDLEISGGQIIGDRHRHTGT-------TGQWGQGIMIRGCRRVTIRDMRISDCWGDGMSISSI-RLNGRYDPWTPSNDVVIANVVSTGNRRMGLTLGGTRNIRVHGCEFSNTRG--IEPGCGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>R6GIV0_9FIRM +-------------------------------------------------------------------------LTVHSGQRLLFD-AATFQLTANGYDFYAVLNIHNVNNVTVEGGlTIIGDRESHTAT-------TGESGHGIRIVNSHNVHVSDVDIRYTWGDGVCVGGNGTM------AEISQNVTLERIRTYKCSRNGLSIIEADGVVVRDCDFTYT--DRTAPQYGIDVE------PNLGTATNITIENVRMLNNGIGGFALYTT----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A088F0B6_9SPHI +-----------------------------------------------------------------------GGVALSSNTIVYGNNAKITAFADYNQPAYNIFRIENIENVIVKDLELIGDRNSHTGTL-------GEWGYGIAVLGSRNILLNNVVSKNMWGDGVNIQMLN-ANQAGVTQdTHCSNVTLENCIFSNNRRQGLSIEDGSTIRVSGCTFDKSNGKA--PQCGIDIEPI-VAGRAFVD--GVTIEDCMFSDNeNSGILMESLNGPISnvtiqncffhHKKAKISNAVYIGINTSRNNLNTKIL--GNTFDKSLDrslyiTGGMYMAISGNYIakefivNSTDTNLPEFYTDNLV------IDNNTL--LSGLTLESGVRK-VTISNNKIESpirPNTSSIGIFNKSQRLIANNNefNNCETGIHSYNTTTTSAI-INENIFKNINIGVVAQLNS--KIISNQFINTGinktSGYG--------------------------------------------------------------------------------------------------------------------------------------- +>SRR5512133_1390 +-----------------------------------------------VSVPDGTYMINALTS-----------VLLKSNMTFSMSSGAVLKAITNSSSNYSILFANGVNHVNIIGGTIQGERTTHTGT-------GGEWGFGVRITGSQQIVVEKVLAKDCWGDGFYVSA-------------SASITLCNVTADHNRRQGLTITSVDGMVVRNSTFKNTQG-TL-PEDGIDIEpNAGET------VNNVLITGCTFTSNSGFGV------EIGVPISYTGQAWIKGVVVDgNTVTGSGVNTLSTSPRAGIEASDIPS--AGNK--ITNNYCANNGLGILLRngSNGMTISGNTVTQNTTDGIQVYSTDGNTITGNTATNNLGRGIYSTSNTNISISNNTVSG------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1X6W0S9_CHLAO +---------YLIDVNEWGISNDGTNPLETTQGINNALQWAYQNGYSYVKLPEGVYTVSKGSASKDYSENACILLQNDTTLDLY---GCVIQKEANGWDYYAAISIVEKRNVTILGGKIVGDHLAHDYATL--ANSIHEGCIGIIVeRGSRNITLNGVEV---------------MNFPG------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>ERR1035438_889792 +-----------------------------------------------VMVPDGTYMVNAV-------AQNAAGIRLGSKMTMKLSSGAVLKAIPNASGNYAILAVSFASHVTIVGGTLLGERGSH----TGTDG---EWGMGLSINNSAHVVVQDVTAKECWGDGFYVT------------SLSSDVTLCGVVADHNRRQGLSVTSVEGLVVRNSTFKNSVG--TAPECGIDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>WorMetHERISLAND2_1045183.scaffolds.fasta_scaffold180453_1 +---------YYLDPVVAGITegvVSDTIALANTVAINTALETAKTEGNTTFVVPTMDAYFDTGGNGNSREEEVSGAIQIPDNMHFKMGAGTVLRRQPNDkhhssllsviykpptstNRGYGSL---LGENVEISGGTLIGDINDHTyyvgatitspattttasiriqreyvptvyeipvtisnvttnateiasyintnlndmeatvdgatvwitpnqglYVLMDDDNTdlsniemvytpdyTFEFGFGISLYGAHNTYIHDITIRNFHGDAIFIDKTGLRNIDATLpsnFRTCENVLIQRAYMQNNRRQAISVVDCNgyednvalptpggagsrvGVIIDNCDIVDTGRDIYHlPAYGIDLECYRQLGAEYARVENVIIKNSRFSGNRKGDLNLYNSQYVQVFNNEFTYKIGHVASNNVSIHDNTFTYDPIVYPENTDnSVAISlfsyiaqdgITELVYDFDIYSNTISGYTFGIIVSGDRFNVYSNNISN----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_498154 +-------------------------------------------DFGSIVFPSGTYMVDG---NDPAGPGGRQGVRVPSNRAISWLDGAEVRVIPNSNTGYNAFLVDQVENVLFLNPRIKGDRDEH-------TGVAGEFGMGIEIRSAENIVLRDPYIYNCWGDGIYI---GQVSEAA---GPCKDIYIERGKVDNNRRQGMSVISVDGLFVDNTQFTNTNG--TPPQAGVDFE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A0Q9EPM5_9GAMM +----------------------------------QAVIDALPADGGTVYVPAGNYIIDPTRNLRLR-----------SNMHLQLADGAKLLAKRNSADRAYVLMAYKVSDVEISGGQIVGDRDNH----LGT---TGEWGHGVMVRGSSRVTIRDIRISRCWGDGISVGGAIVTGLPTVI---SQSVVIANVASTGNRRQGLSIGRSSEIKVYDSEFSDNVG--IAPGCGIDVEpdandlgttttvhienclitGNQGNGiQVYKRVKGITIKRCTIEYNgGYGILTiAPVSGYIAlnrIAHNYLMGVMLRSATTSYQVSGN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2G6EWH0_9GAMM +-----------IDVTDAGYDAKGDGTTNDTTAIQKAIDAVADAGGGVVWIPKGRYMIDTEARLKMR-----------SNVTVQMTDDTVLEAIPNGAGSYSIFRFYNVENAHLLGGTLVGDRDSH----LGT---SGEWGTGVNISSSSNIRVENIVTKDFWGDGFYIGENGSLD-------KSENIVLYNVVGDNNRRQGLTIVNGDNIKIIDSTFQNTHG--TAPAAGICIEPNDNN-----LVSNVEILNCKTINNDGDGIGLYE--RVNAINNEIEN---------VRVDGNEIIgNSGGIIVSG--SV-TDSTITNNFINTmeTDSSEPGIRL----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_10317103 +----------------------------------------------------------------------GASIRLHSNSQIVIAPGAMLRAIPNNLNNHALFYCYDAENVYVTGGTLLGDRDDH------TDAEDGvNAGMGWRISASSRVTVERQRILDFWGDGIYV-RNGTVETED-YDTLSTQVEIRQVECNNNRRTGIAAAGVEGLTVWKCWLRNTNGANpfAGANFEPNIDGYvrnvqvqnslaeGNAGAGFQtSGHDVTFDACTGRGNGtNGFRILNTTG---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>S3Y1Z0_9ACTN +---------------------------DDTAAIQRAINQASDAGGGTVNIPGGTYMInpiavDSVHGLMMRN-----------NVTLKLADDAVLKALPTNTTHYSLISFVKVENANLVGGTLIGERYQH-------TGQGGEWGHGVNIQSSQKVTVQDVTSKDFWGDGFYIGQAWQV-------WDARSNQVALCNVTsvNNRRQGLSIVDGTNIRVLNSTFSRTNG--IAPQAGLDIE--PENGNLVEN---VEVRDSVFSENlGDGI------------------VLTWGEQNDASIKG---------------------------VRLESNQVLDNESGIMLhRAIGCQVINNTIRNAGN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_4714463 +-----------------------------------AIDYAVEKSIDLVWVPKGVYMIDAAGVNGEK------GLRLRSGITLKLHEEAVLKAMPNNVANYSILRVYDSANVKITGGSILGEKNEHTGT-------GGEWGMGIDIQSSNNIEISNVKVKECRGD-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1041385_954775 +----------------WG--ALGRSSPDQTKDDTQALQAALDSGARKVTIPNGHFMIDAARVQPGRTK---AGLNLPSNIELIMGTETFLHARNNSSISYNILVGWKVSNVIIRGGVLVGDN-------VTNSRRpdSNPSGFGLALFGAKNVWVYGLTSQEMFADGFFVCYD---DEPGS-HDECENVHLMDCRAYKNYRQGASVIGAKNSSIEGGQYRQTGGSP--PQDGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5581483_5383682 +--------------------AMGNGSMDDTKAIQAAIDALPESGGTII-VPNGTYMIDALK-----------GISLRSHDRLSLASGAALKAIGNSERRSWVVKVWNVNNVEIVGGGVIGERYSH------RGTSGGEWGYGINISSSDKVYVHDITIQDCWGDGLLIGALG--SGKGMV--EATNITLNRVKSKNNRRQGMSITPANRVYVVNSSFTGTHG--TAPESGIDIE---PRSQGWASQVRLENTDLS-NNNGNGlevhhNVDALTLYKVTAKNN--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1G7HPV6_9FLAO +------------------------------------------------------------------------GLRIRSNSKLYFQKESLLKLKSSAKVLYAILNIAKVENVSIYSPTIEGDRYRR----VNPEDKKGEWGMGIWIQESKNISVFNAKVTHCWGDGIYIGG-------GRDIVPNDSIYIHRPIIDENRRNGISITSGKNIRIIEPVVSNSRGKS--PESGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1G2Y1Y7_9BACT +-----------------------------------------------IRFPAGTYAIDGFDeTIDKdGNVTVYGGLKPASDTTLIFDIGAKLKAIPNDKIGYSILKIEGKNNVKIYGPTIEGERDSHTGT-------TGEYGMGIMLEGATNIVIKDANVYNCWGDGLLIGVHWT--------KPSDQIYVENSTFNNNRRLGCAVTNGTNILFKKCTFLNSNG--TAPQAGVDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1035438_766262 +----------------------------------QACINAVAGTGGTVVVPDGTYMI------NATHGSGVWGLMMGSNMTFAMTSGATLKAITNSSTDYGILCSNGASNFTITGGNIVGERSTHTGS-------GGEAGMGIYLNAS-NVTVSGVNVSECWGDGIYIC------------DASSNITITNCISNHNRRQGLSITAGNTFLISGCTFSNTTG--TDPQCGIDIEPNGSVPVTGVH-----ITNCQIFGNAGGGVQQGNVGNV---------------ASGTLLENCNIYSNGGG---GYNDGGIRFVETHDNI-IRNNNIHNNLNGgiMLDTNAGIGCPNttltgNTVANNSGWGIYANLCNGSAITGNTI-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_3394488 +----------------------------------------------IVDVPAGTYMIDAETSILMRD-----------NTHLRLATGATLKAIPTSSAVYNVILCELVDSVEISGGAILGERDAHTGT-------GGEQGHGIRSRGATNVYIHDIHISKCWGDGI-DAGPDKSDSHNYVYT--ENLTIDNVVCTQNRRNGLSIGNVNTARVTDSEFSYTNG--TSPQCGIDVEPDGDADGDGDCS-DIVIDNCRLNNNAVYGINLYQRARgVTISN--C--VIEYNSSCGIVSNG--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR4249919_325582 +-------------------------------------------------VPAGKYLINPVRVASGTS---FYGLLVGAGKRLEMDPNAVLVLKPNSAPRYCGVRI---DGGYMQGGQVLGDRLSHNYS----SGGTHEWGYGVQLRGTDSKAV-GVKVSQCTGDGF-----GMSGI---------RPVIENCISTQNRRQGVSLFGSDGLRISGCEFSNTGAlngqAGTNPRCGVDFE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1E8BK68_BACMY +---------YFLELERWNVKNDGTDANNTSKGINNALLWASQQGFIEVVLPMGIYLID------ENTP-----IEPQSFMTLNLG-GATLKIRDNGLVKYAIVrYQRNQKFSRITNGRIEGDKDTHDYTTIP---HTHEWGYGIEVgnttpiEGSniSYISIDNMEILNCTGDGI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>SRR5512142_681238 +-----------------------------------------------VYVPRGTYLV-----LADGYRDGGrGGLAPRSRTRVVLAPDAVLQARPTGSSDYVVVRIERVSGVTVEGGTIRGERHEH------TGRGG-EWGFGIGIFGASDVVVQDVTIRDCWGDGLFIEE----AQPDFSVMP-RNISIRRVVSANNRRQGMSVPG-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>D7W8T5_9FLAO +-------------------------------------------------------------------PLMTSGIFAQSNSQIYFQKNSSLILKPTADVRYQIISLHAVENVKIYNPTLIGDRDRHLGS-------KGEWGFGIDIRGSRNIEIYNANISDCWGDGI-VLVKTMRNMRSGVakenIFPTENINIIGGFINNVRRNGITIAGGKDIIIKNLLIANING--TNPMAGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_487370 +------------------------------------------------------------------------GIVLSSNTNIYFDVNSKLILKQSSKESYSMLKIYNVENVNLFNVHLVGDRYQHIGS-------EGEWGMGIRIQNAKNINIYNSTIRDMWGDGIYITSFG--------NTSNQNILIQSSWIDNTRRNGISIISGEDINIDYVKISNTNG--TAPASGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>H6LBC8_ACEWD +-------------------NAKGDGKTDDTSAIQNAL-----NKSDSVYIPDGTYMIN-----------VDQSLKPNSNQTITMNANAVLKAISSSRGEQYVITIDGVTNVSIIGGKIVGERNEH--QGLDG-----EWGMGINvVNGSSNIVIKDTTISDCWGDGIYLGGSPAVN----------TITIDGVTSDNNRRQGLSITNAKNVLINNSVFKNTNG--TAPEAGIDIEPnvnqaaedikimntqcYGNNQSGIDilgnngGIQRVEITDCTIKDNvGLGILLFEASGitfaNTSVTNNKDDGV---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6185312_3767693 +------------------VGAVGDGTTDDTWAFQKAIDSVAAQGGGTVYVPAGTYLIDADVSINMKD-----SVTLD-----MVDTTRVLMAKPTATVRNYVIKLNNISNSKVIAGKIVGDRYQH----LGT---TGEWGMGMGINGSTNITVTGTNIIDCWGYGITISSYNCV---------LKNVI---CD--NNRRQGLTIGSSDSLIVDSCTCTHTNG--TAPQDGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A0D5BSE2_ELIMR +------------------------------------------------------------------------GLVLNNNQVLLFQEKSVLKLNPTTQKEYSVLGLSNVNNVKIFFANIEGDKYQHLTNV-------GEWGFGIGIFSSNNISIYSPYIKQTWGDGIYIGQ--------IKNIPSTNIQVYNAVIDDVRRNGMSITSAKNIDVVNAYISNTNG--TSPESGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_13262863 +------------------------------------------------------------------------GLKLRDNSKVLFQQNSVLILKPSSKSQYSIILMDGVSNVKVYFPKIKGDRVGHKGT-------KGQWGMGIWINNSQNILVHNPYITNCWGDGIYLG--NVNNRP-----PNKDIQIIDGMLDNNRRNGISIISGRNVEINGTFISNTNGHN--PQSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1035438_2623855 +------------------------------------------------------------------------GIRFGNNMTLRLDSGAILQALSTSSSSYRILLLSGVQNINIIGGTIIGNR--NNNTITDSV----EDGMGIQIANSQHVVIEGVTVQDCWCDGVYVS------------DGSGDVTLNGVVAKNNRRCGSAIVSVSGMVVRGC--------TFQGTTGMMENGLWANGTGVDVEPNLgeTVQNIQFLGN---TFTQNATGGLGIGPSNAN--MATTFVINCVIDGNTVSSNGDAVK---GTFGIVASSTGGH-QILNNTVtNNYGVGIYLYGdaSNILIQGNTVSGTS--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2A8TS41_9BACI +-------------------------------------------------IPDGTYMI---------NADI--SLKPNSNQILSLSKKAKLKAKPNSDASYQIINIIEKENVIIEGGYIEGERDEH----VGVNG---EAGMGISiVRNSKNITIRNTHISKCWADGIYIGG----------YLPCYNINIYNVTCDNNRRQGMSVVNVDTLTVRDSFFTNTAG-TL-PEAGIDIE--PEN---YSTVKNVTIDNvvCTGNRSGLDVFgWAKTISNVQVLNSSMINNREYGlsiaFTTDILV----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5687768_6663082 +-----------------------------------------------VYVPAGTYLVDATRT-----------IRLRSRMHLKLDPGAKLLAKATSADRYYVVNAYKVHDVEISGGQIVGERDRHIGS-------SGQWGHCIGVRGCKRVTVRDIRLSKGWGDGISIGAAN-----GTTTVLSDDVAVANIVSTGNRRQGMTIGRCRNVKVYDSEFSYTSG--IKPGCGIDIE---------PDPFgtivcdTIRIQNCWIHHNaGNGVQVYKTVKNVTIK----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_2031064 +-----------------------------------------------------------------------------SNSYIKFHPDAVIKVNPNNYGDYDRKYgviiIYMKDNIVIKNPRIVGDKHEkpKNYKKIDSE----EWAAGIQIeRKSNNIKILNPHITAMWGDGISdSAGRKSMGEP-------DNILISNCFIYDNGRNGYSITASSNTKVFGGIISKT--DRTEPISGIDVE-----PAQYSRDVSgLNIKDVKF-TNGRGLILFKASQGAVIED---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5688500_1121635 +---------------------------------------------------------------------------------------------------------------IVGPGRITGARMVHRGS-------SGEWGMGISAWNSTNFRITGVEIADCWGDGIYVGSAGNGYCDGFLI---EGVKVRNC-----RRNGISVVAGRNGEIRNLDIAKI--DGIAPRGGIDLEPNSSNAPNRN----IRMSNGRIRDVAVGIYVTVANQRVSISgmDIEAENsgIIVSDNSVDVRIENNPNIKSlIGGKEGGAFRTVVTRPETIRGLLIRNNQLSGggaFVIDIFGQGyQGLVISGNRISatNAGTQGIA---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_32025263 +------------------------------------------------------------------------GLKVKSNSVLEFQENSLLKLKASDKHTYNILEIHSVQKVKILNVKIKGD--------LDTHiGKDGEHGMGISIRSSKDVEVVNAKIEDCWGDGIYIGRLNRYDRNGM-FEPSENIIIRDAYVNRNRRNAISITAGRNNLIDKLDANKTKG--TFPIIGIEIK---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5579883_944156 +-------------------------------------------------------------------------IQLRGRQEIIFEPGVVMLAKKGEFRGTGDSLLSIVgqSNLVLRGYGAILRMHKPDYQA--EPYKKGEWRMGIAIRGCKNVLIEGLRVESTGGDGFYVDGGADRGW-------SEDITIRNCTAYDNHRQGLSVISAMNLAVENCVFASTRG--TPPEAGIDLEPDTEENRLVN----CLIRNTVFQNNNGHQVLIHlkplsrKSMPVSIRFENC------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1T3DZL3_9FLAO +---IKKDGSYYERQFEGGINPAWYGEL-TEKSINKALHIASVLN-------------KDVELMNDYKIDCSGidtGVKLLNNSVLRFSNNARLLAIPSSSGNYRMLSIDKVKNVKVYNPVIIGERSAH----LST---TGEWGYGINITNSQNVEIHNAVVKDTWGDGIYIGG-DYFDKTQTISTLTDNVLIYNPYIDNVRRNGISICSVGKVRVYNAVIKNVNG--ANPQSGIDIEPEGDTG---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5699024_10516162 +-SLLDRIVLYVDDF-----GAVGDGVSDDTDAIQQALNVAGELRTSVIFTKGKTYMTDG-----------SKGILPPSYSTLIMTGSKL-EVIPNALDRYICLYVLIAEHVTIIDPDLKGDRSNHittpSTNNNNVDGFTGEWGFGLRIARSKNVNVYNCKTSDFWGDGVLIGTDGIENTP------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5262249_48802186 +---------------------------DDTSAIQAAIDAVAEKRGGTVLVPNGTYMVSAVR---------DNRLSLKSNVTLRLANDAALKAIPNDSDHYSVLRIANVSNVAVIGGTFEGDRNEH-------SEKTGDWGMGIWIgKGAEHVTISGVTATKMWGDGFYI---------------QDANDVRLCSVvaENNRRQGLSIIQVNGLEIKNSTFKNTHG--TRPSAGIDIEPDNDE----QHVANVRIHDSKFLDNaGAGIAVVAKKSLVS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>ERR1700750_2813068 +-----------------------------------------------VEVAAGEYLID-----------VTKSVKLRSGVALVLDPDATLRAIPTDAGNSAVIRIHDATGVRVEGGSIVGERDKH----LGTNG---EWGMGLGARGSHDVLIQDVLISGCWGDGVYVGS-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR2546423_7159601 +--------------------ALGNGVVDDTAGINAAIRSLAGTGGSVL-IPAGVYLVD---------PTV--SVQMASNVSLLLDDSAILQAVPVAAKSYAVIAASGVHNVKISGGKIIGERQTHLAA-------TGEWGMGVRVMGSSNVQIERVE--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5680860_103890 +-----------------------------------------------VLVPNGVYMVQAV----------GESLALGSKMTLRLADKATLKVIPNGETRYYTLRIHEASDVTVIGGTLLGDRRAH-------KGKKGEWGMGLHIVRSSRVTIAGVTSTRMWGDGFYVA---------------DGTDIAFCSVAaiNNRRQGLSIISANRLLVTDSVFRDTRG--TRPSAGIDME-PNKASQRIAH---VRIERSKFIGNaGDGIVIQGYKGRVSnveIRNNLFD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A1Z4RLG8_9CHRO +------------------------------------------------------------------------------NQKILFQPGVVLEAQPGAFKGkYESMVSVMADNVTLSGYGAEFKMRKADYANPSLYEKS-EWRHNIHVRGARNFIIEGLTLKDSGGDGI-LVEHGPNEPNQLPVSKYSSGTIRGINASDNYRQGISVVSAKDLLIENSTFQNTSG--TEPASGVDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2B2C9D0_9BACI +---------YILELDVWSvsntVSDFNDKTLSTanSNGINNALTWASQRGYSEFMFPKGTYLIDE-------------NIPIqPKNFMTLNLNGSTLRIRNNGLPKYS--VICYRQNQIfsrVTNGIIQGDRYDHDYSN-PGELPTHEGGMGILFPNTTDpskgegtntlfTTIDNIEFLDLTGDGV-----SLFSSQGLVYattTPTKSYAI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A2C2T0P3_BACME +---------------------------------------------------------------------------------------------------------------------------------VDNERYTHEWGQGIEIAGSNHVEIKNIEICDCTGDAV---STGWLKYrtNSTDYTQNEmghHIWIHDCDIHHCRRQGITLASANDVCVYNNKIHHIGkaddnvtsdfRNGIPPMFAIDIESmVGESNIPYKQPYynkdglelnfRLYIFNNHIHDNQRGHFVNADGNHVTVENN--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5215813_7905647 +-----------------------------------------------VFVPKGVYVVDAV--AKKRRLTLG------SDMTLKLDNDAVLKAMPTDSRKYSILTVSGVSNVTIVGGTLEGERAQH----MGNDG---EAGMGIRiVGGAEHVTVSGVTSRKMWGDGFYVEDANDTKFCG--------------ETSDGnRRQGLSIIEADGVLVTDSVFSNTHG--TRPSAGIDLE--------PDHPSQqivnIRIQNSKFLNNaGPGIEIAGKKGLVT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6185312_5921845 +----------------------------------------------------------------------------------------------------------------------VGERQNHVYSGIGTG--TDEWCFGIQILGVTGMTIRGTQISQCTGDGIDLGNFGS--------SISSDIVICDVISTQNRRQALSITGGDGIFVYDSEFSYTNG--TAPLDGIDIEPGGAGAS------NITIENCLIRGNtGCGiQLNAHWGDIINVNVKNC------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690625_4101829 +------------------------------------------------------------------------GLEIHGNSTVFFDEGSVIKALPTSNGNYSILSIKGVDNVKIYNANIFGERNEH-------QGDTGEWGMGIRIEDADNVLVVNLKVSDCWGDGIYL---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1H6XJ90_9FLAO +------------------------------------------------------------------------GLNLRSNSVLVFQENSYIWLKASSKPNYGVINIKDIKNVTLINPRIVGDRDSH-------LNKIGEWGMGINILNSDYINIFNAIISKCWGDGIYIG--------NKINGFSSNININGGLIDNNRRNGISIVSGEVVVIKDITVSNTNG-TL-PMSGIDLEPNTNEDTLKDIKL-VNVNSFNNRENGyliyLGGLLGENKREVDISiescfDQYSNTVVSIpGLRNDYEKKVKKI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>SRR5512133_257377 +-----------------------------------------------VTVPDGTYLVNALTS-----------IQLRSSMTLSLSGGAILKAIPNSSSSYTILRISGVSNVNVVGGTLLGDRSAHAGT-------SGEQGVGLRITGnAQHIAVVGVTSKECWGD-------------GFMVADASDVTLCNITADHNRRQGLSITGGNGIVVKNSSFINSQG-TI-PEDGLDIE--PNSGQIVSN---VLITACVFANNAGDGI---ENGVPVL-------FTGLAFIYNVVIDGNTMTGNGVGTLHAGPRSGIEVSNTSGHV-IKNNTIQstaGYGIYLRDGVAGTTVTHNTVtKNALN-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A110B3A3_9SPHI +------------------------------------------------------------------------GLSLISNSTVIFRKYSKLVLQANGLPAYQILRIYNATNVNLYFPVVQGDR--------DLHSGNGQWGMGISISGSTKILVVNPKVSKCWGDGIYL---GRQN-----NAVDRNITIFYAELDNNRRNGLSITCADGVHLIRPIISNTAGQM--PMSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A229UP75_9BACL +---IGSPVSYAIELDRWGIQNNGTDAETTTRGINDALVWAKSAGYNHVVLRGGTYLI-------QVDPN-GTAIYMPSGMHFEMHHDCILQLAGNSFPNYRMIEMKGIRYAKVSGGKMIGDKAFHQYEM------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5262245_13989197 +-----------------------------------------------VVVPNGIYLIDAAGE---------NRIKLKSDMVLKLSDGATLKAIPTDAENYALLTIADASNVWVIGGTLEGERDRH-------KGKSGEWGMGIRIgEGAKYITIMGLTSRKMWGDGFYVRG---------------AEDVRLCGVtaDANRRQGLSIIEADGLLVQKSVFKNTRG--TRPSAGIDF----EPNRDSQEISNVRIENSKFLDNaGAGILVAGKKARIT------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5215831_1849565 +-----------------------------------------------VLIPAGTYMVNAVDS---------NRLSLKSNVTLKVANTAVVKAISNDSEHYSVLRIANVSNVAVIGGTLEGDRNQH-------LGKDGEWGMGIWIgEGAEHVTISGVTALKMWGDGFYI---------------QDANDVRLCSVvaENNRRQGLSIIQVDGLEIRNSTFKNTHG--TRPSAGIDIEPDNDE----QHVANVRIHDSQFIDNaGAGIAVVAKKSLVS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>OrbTnscriptome_3_FD_contig_123_161973_length_414_multi_3_in_0_out_1_1 +-------------------------------------------------------------------------VKLRSNINIVFEKGVVVladEASQKGNAKYPMFEVKNVSNVAFIGrGDKPGDVYIGKYRDNEERRRmCHDYgGSGFAIEGAQNVVIRNVKVAECSVDGISLSSLGRLN---------SNIYVQDVILDGNYRQACSICNADGLYFKNvAFLNTSGGD---PMCGIDLEPTYE----LEPNSNIYLFDCRFEGNVGGGLnfTSSSYYPVTLHAKRCD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>SRR5262245_2037218 +-------------------------------------------------VPNGVYMVSAVE----------NNLKLKSDMTLKLAGGAVLKAIPNDATHYAILTISGVSNVWVSGGTLEGERSEH-------RGKLGEWGMGIRIDDrAKNITIAGLSSKKMWGDGFYV---------------QEAEDVRFCGVtaDANRRQGLSIIDANGLLVLNSTFKNTRG--TRPGAGIDLE-PDKDAQQITH---VCIENSKFFDNAGGGIMVAGNKKARV------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +>A0A0D4DCI2_9CAUD +--------------------------------FMVGYIYATSKNRPfVVDIP---IYVQSTRKQSGFYNQVHYAVVAQSNSILWFMPEGeLIQIGVD-EAAYSILSLYGADNFLIKNPKLRGDKY-------TKTGNTGESGFGLTVTGCSNGIIEYPNISECRGDGIYLGQEYFNNNASSLI--PKNIKIIKPTILDSYRNGLALSAGEDIYFDAPFIDIAKG--TAPEACIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5688572_15557399 +-----------------------------------AAIQAAINSLPstggVVSIPAGTYLVDTTKRINLR-----------SLMLLSLASGAVLKAKTSSVRRAYILNVNNVRDVEIAGGQLVGERDTHKYVSGTTD----EWNHGIAINGSARVTVRDIRISKC----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6266566_4873650 +-----------------------------------------------IHVPPGTYSVDAV----------SGSINLKSGITLDL-TQATLVANPNNQIFSIIMRVSDCENVTILGGTIRGERTTH---LGSTAAFMGGGGGGVAIWRSKNIKIQGMKISDCFCDGLLVWHSGQVEIanviadhnrrQGMSLVDSHDVHIHNSQFTHcggtppgdgiDIENDLETETCANILVEHC----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>G2KPW0_MICAA +---------------------------------------------------------------------------------------------------------------------------------------------GIEVQGGKTVTVSGNNMDDVRGNGIQIsSSQGAVNlldnvvsdirlHGIVVNTAPGAVVVDGNRVTDAGEFGIYTNGSKNVVVSDNRVS-------GGKNGIVVQNAAAS-AKIENNVVSGASDAGRVASGYqtaiGILVKDSAGAVSVTDNRSNANTGDGiriLNTDGAVVSGNITNDNGDK-------GIIINRSDNAV-VDDNRSNGNATGIWVElSNGVDLTNNVIRHSKVDGIHLRDSDNTLVQGNQIlsNDRNGIFVERSDSADIFRNTITGSGGYTGVKVEGSSNTDIGATDQT-SWVQTGFWPWQGHFVtTVRGNTITNFDNGVTVAGGNDNDV--VRNTISgVDYGVRLSGAT---NSDVLGNDLTG-NSIVGIEVVAGSHNAVIDNNTLDHFDT----GIVVNGSNNVDVTDNDLTDVGSGIVA----------------------------------- +>SRR6266511_2426516 +-----------------------------------------------------------------------GGLVPRSNTHLHLAPDAVLKAKTTSASDYNVVRIERVSNVVVEGGTIAGERHRHAGS-------GGEWGYGIGIFGATNVTIRNV---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1Q6A375_9SPHI +------------------------------------------------------------------------GLTLHTGQKVYFKKGSVLNLVPTAQPNYEMLRIHDVTNVSVYNVVIKGDKYSH---LV----KTGEWGMGISIRGASNINIYSAKIEQCWGDGMYIGTTPKQAF-------CENINLRYVNCNDNRRNGISVISARNVTILGPVLTNTSG--TQPMCGLDLE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690554_4058803 +------------------------------------------------------------------------GLNIISNQILNFSQNSKLIMKTNAEERYGILNIKYVKNVIVNNPNLIGDKEKH-------LGNRGEWGMGINIWASKDVTINNPRISETWGDGIYIGEPPVQE-------------KQKKKLKSYANHNIAIN---GGVIDDC----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR6516164_3930632 +-----------------------------------------------VLVPNGTYMVNAVGDAR---------LFIESNVILKLANDAVLKAIPNDSKKYSVLRISNASNVAVIGGTIEGERYGHSGNV-------GEWGMGIWIgEGAEHVTISGVTAAKMWGDGFYI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5262245_45879959 +-------------------------------------------------VPNGVYMVSAVE----------NNLKLKCDMTLKLAGGAVLKAIPNDATHYAILTISGVSNVWVTGGTLEGERSEH-------RGKLGEWGMGIRIDDrAKNITIAGLSSKKMWGDGFYV---------------QEAEDVRFCGVtaDANRRQGLSIIDANGLLVLNSTFKNTRG--TRPGAGIDLE-PDKDAQQITH---VRIENSKFFDNaGGGIMVAGKKARVS------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>SRR5690606_56255 +----------------------------------------NENN--VVIIPKGTYRVT--------------GLKLKSNFSLLFEEGAELELIANNKERYEILSLAGIKNVKIYNPVLIGD-------IRKRNSLKGEWGFGIDIRGSREIDIYSPFIKDCLGDGIIIS--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +>A0A1I0S8N9_9BACT +------------------------------------------------------------------------------------------------------------------------------FATIEGDRSTHkgaagQWGMGIAIRAAKNVNIYAPRISKCWGDGIYVG--------GLKGVTSSNINIYNAMLDYNRRNGMSITSVSGLKLVAPVISNTYGQT--PMSGIDIE---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/test/unit/data/uniprot.mode2.txt b/test/unit/data/uniprot.mode2.txt new file mode 100644 index 00000000..17b94b62 --- /dev/null +++ b/test/unit/data/uniprot.mode2.txt @@ -0,0 +1,120 @@ +>O31912 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A6H0H3G5|A0A6H0H3G5_BACIU Right-handed parallel beta-helix repeat-containing protein OS=Bacillus subtilis subsp. subtilis str. SMY OX=535024 GN=HCN55_11075 PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A162RH73|A0A162RH73_BACIU Uncharacterized protein OS=Bacillus subtilis OX=1423 GN=B4417_1688 PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A6M4JNF4|A0A6M4JNF4_BACSU Right-handed parallel beta-helix repeat-containing protein OS=Bacillus subtilis (strain 168) OX=224308 GN=HIR78_12405 PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|O64135|O64135_BPSPB YorA protein OS=Bacillus phage SPbeta OX=66797 GN=yorA PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>sp|O31912|YORA_BACSU SPbeta prophage-derived uncharacterized protein YorA OS=Bacillus subtilis (strain 168) OX=224308 GN=yorA PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A857HHC0|A0A857HHC0_BACIU Prophage-derived uncharacterized protein OS=Bacillus subtilis OX=1423 GN=Bateq7PJ16_2250 PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVKGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A410R1H8|A0A410R1H8_9BACI Right-handed parallel beta-helix repeat-containing protein OS=Bacillus sp. WR11 OX=2448811 GN=D9C22_10995 PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFSIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNTELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGVSSTETSNRIQITDNNIQGFKIGMMIRGKGVSVDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSTYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGTRVLSHPYATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A7G5CIE1|A0A7G5CIE1_9CAUD NosD domain-containing protein OS=Bacillus phage vB_BsuS-Goe12 OX=2586960 GN=hypothetical PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNLNPIETTKGFNEALIYASENNFPIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGFSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVCNNKGKGTTSTYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYFNGTKKVRLIRNDVQGIGTRVLSHPYATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A7G5CIX1|A0A7G5CIX1_9CAUD NosD domain-containing protein OS=Bacillus phage vB_BsuS-Goe13 OX=2586961 GN=hypothetical PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNLNPIETTKGFNEALIYASENNFPIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGFSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVCNNKGKGTTSTYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYFNGTKKVRLIRNDVQGIGTRVLSHPYATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|G4EVD8|G4EVD8_BACIU Beta_helix domain-containing protein OS=Bacillus subtilis subsp. subtilis str. SC-8 OX=1089443 GN=BSSC8_22190 PE=4 SV=1 +MTLLNKSIRYYVDFDQWGINAFNLNPIETTKGFNEALIYASENNFPIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGFSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVCNNKGKGTTSTYAIKVMDSNDVTFINNKFSNLYGGLYCERSQSIRIKQNDFLLSGKGYGIYWDKDSKVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGSRILSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>tr|A0A7G5CHW7|A0A7G5CHW7_9CAUD Beta_helix domain-containing protein OS=Bacillus phage vB_BsuS-Goe11 OX=2586959 GN=hypothetical PE=4 SV=1 +MILLNKSMRYYVDFDQWGINAFNSNPNETTKGFNEALIYASKNNFPIVEIPKGNFIIDSVNTLNQRNPEVGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGHIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVKISDCIGDNIWIAAHGMMNYPGMAYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGVSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSTYAIKVMDSNDVTFINNKFSNLYGGLYCERSQSIRIKKNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIVFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGSRILSHPFATFNASSTTLIHNTYDSGTPRLALDDTLIDYK +>tr|A0A837Y204|A0A837Y204_BACAT Uncharacterized protein OS=Bacillus atrophaeus OX=1452 GN=B4144_1968 PE=4 SV=1 +MNMIDKSLRVHVDFEQWGINPEGLNPIETTKGFNDALQSAASNFYSVVEVPKGNYLIDAVNT-SKRLPEFGGGIKIPSNIELILHPEAVFRVNPNGYQGYSCFYIGQAENVTIRGGRIIGDRYEHDYSKINTIQKTHEWGYGIHVHGSRNVLIENVSVSDCIGDNIWIAADGMMN-TDVTYTPSRSVTVRKCRLKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGFAEKGIKYDHPYELTIADCRFKKNGRGSITAHTSGKVIIKDNYCDNVISYGFSTDVSIKGNKIINEGEPKEYGIDSIGVSSTETGNRAKITGNTVRGFKIGIMVRGRGVTAKNNTIGNSSNCAIATHTAEEVFIAKNKIENSNCIQIQVRNSSDVKVNGNTGKGTTSSYALKVIDSKDVTLTGNEFSNIYGGLYCERSQAVRVKSNDFLMRGTGYGIYWDKSSEVFLTRNEIYEPRNIAITGTADIYNIRISENQIYNCKALVAIHLLGGSDHMLRGNEIMFNREADQGYGIYLESTKKVRLIRNDVQGIGDRVLSHPYATFKSSNTTLIHNTYNSGTLRLAVDDIVI--- +>tr|A0A150FBD2|A0A150FBD2_9BACI Beta_helix domain-containing protein OS=Bacillus nakamurai OX=1793963 GN=AXI58_10415 PE=4 SV=1 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGFNRALEYASSNSFFRVYVPKGKYLIDAVNT-TKRLPEFGGGIYVPSNIELILHPEAVFHVLPNDYQGYSCFYVGQASNVTIRGGQIIGDRYEHDYSKINSTQETHEWGYGIHIHGSKNVLIENVSISDCIGDNIWIAAYGMMNTSG-TYTPSRNVTVRKCTLKRGRRNNLATNGCEGFLVDDCDIEEAGGDTIGPQLGIDLEGFGEKGIKYDHPYKLTVRNCRFKNNGRGSITAHTSGKVIIDGNYCDNVISYGYSTDVSIKNNKIINEGSVKTYGIDSVGVSTTESGNRVQIDGNTVSGFEVGICARGKGVTISNNTLERIKACPISTHQAEDVLITDNRMENSDCIQVQVRNSNDVRVVNNKGKGTTTAYASKIMDSTRVSLINNEFVNVYGGVYCERSQSVRLKGNDLILSGSGHGIFWDKDSSVSLHRNEIHEPKNVAIKGTPEKYSCQISENQIYFCKSLIAIHLVGGSEHILKDNEIMFNRSSDQGYGVYLENTNKARLVRNDVHGIGGKLLSHPYCTEKAKNTTLIHNTYNSGTLKTAEGDTIV--- +>tr|A0A109WGG2|A0A109WGG2_9BACI Uncharacterized protein OS=Bacillus sp. SDLI1 OX=1774743 GN=AUL54_20265 PE=4 SV=1 +---MRQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKISAIQKTHEWGYGIHVHGSSNVLIENVQVSDCIGDNIWIAAEGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGEVNLEGNYSDNVISYGYSTDVSVKDNKIINKGKSKKYGIDSVGVSSTESGNRVQIIGNTVRGFEIGICVRGKGVHVADNILENITACPIATHEAEDVFISNNHIENSDCIQVQVRNSKDVRVTNNKGGNTTSAYAIKIMDSNRVSFAINEFANVHGGVYCERSQSVRLKLNDLFLSGSGYGIFWDKDSEVYFNGNEIHNPRNVAIKGTSEKYSCQISENQIYFCKSLIAIHLAGGSEHMLNNNEIMFNRSTDQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>tr|A0A8A5UUR4|A0A8A5UUR4_BACAM Right-handed parallel beta-helix repeat-containing protein OS=Bacillus amyloliquefaciens OX=1390 GN=J4048_10725 PE=4 SV=1 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNITVRKCALLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGEVNLEGNYSDNVISYGYSTDVSVKDNKIINKGNSKKYGIDSVGVSSTESGNRVQISGNTVRGFEIGICVRGKGIDVTDNILENISACPIATHEAEDVFISNNHIENSDCIQVQVRNSKDVRVTNNKGGNTTSAYAIKIMDSNRVSFAINEFANVHGGVYCERSQLVRLKLNDLFLGGSGYGIFWDKDSEVYFNGNEIHNPRNVAIKGTSEKYSCQISKNQIYFCKSLIAIHLTGGSEHMLNNNEIMFNRSTDQGYGVYLENTNKVRLVRNDTRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>tr|A0A4R2A540|A0A4R2A540_9BACI Parallel beta helix pectate lyase-like protein OS=Bacillus sp. BK100 OX=2512181 GN=EV570_101171 PE=4 SV=1 +---MQQPLYYSVDALDWGIDDKGSNAIETTEGINRALKYASSKSFYKVHIPKGTYLIDAVNT-SRRLPEFGGGINIPSNIELILHPEAVFKVLPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKVTSIKRTHEWGYGIHIHGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGQVIIEGNYSDNVISYGFSTDVSIKNNKIINDAETKKYGIDSVGVSSTESGNRVQIEGNTVRGFEIGICARGKGVLISNNTLEGIKTCPIATHQAEDVLITDNRIENSDCIQVQVRNSNDVRVVNNKGKGTISAYAVKIMDSTRISLINNEFVNVYGGIYCERSQSVRLKGNDLLLNGSGYGIFWDKDSSVSLQRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKALIAIQLTGGSEHMLKDNEIMFNRSTDQGYGVYLENTDKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>tr|A0A853LAC0|A0A853LAC0_9BACI SPBc2 prophage-derived uncharacterized protein YorA OS=Bacillus siamensis OX=659243 GN=SRCM100169_02074 PE=4 SV=1 +---MQQPLFYFVDAQDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGTYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIKEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIDGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGIDSVGVSSTESGNRVQIDGNTISGFEVGICVRGQGGTVSNNTLEKIKACPIATHQAEDVLITDNRIENSDCIQVQVRNSNDIRVVNNKGKGTTSAYAAKIMDSTRISLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPDKYSCQISENQIYLCKSLIAVQLTGGSEHILKDNEIMFNRSADQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIYNTYDSGTLKTAEGDIVV--- +>tr|S6FH05|S6FH05_9BACI Putative capsid component phage SPbeta OS=Bacillus velezensis UCMB5033 OX=1338518 GN=yorA PE=4 SV=1 +---MQQPLYYSVDALDWGIDDKGSNAIETTEGINRALKYASSKSFYKVHIPKGTYLIDAVNT-SRRLPEFGGGINVPSNIELVLHPEAIFKVLPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKVTSIKRTHEWGYGIHIHGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGQVIIEGNYSDNVISYGFSTDVSIKNNKIINDAEVKKYGIDSVGVSSTESGNRVQIEGNTVRGFEVGICARGKGVSISNNTLEGIKACPIATHQAEDVLITDNRIENSDCIQVQVRNSNDVRVVNNKGKGTISAYAVKIMDSTRISLINNEFVNVYGGIYCERSQSVRLKGNDLLLNGSGYGIFWDKDSSVSLQRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKALIAIQLTGGSEHILKDNEIMFNRSTDQGYGVYLENTDKVRLVRNDARGIGGKLLSHPYCTDKAKNTTLIHNTFDSGTLKTAEGDIVV--- +>tr|A0A6H3B795|A0A6H3B795_9BACI Uncharacterized protein OS=Bacillus velezensis OX=492670 GN=CHR37_05085 PE=4 SV=1 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGVDSVGVSSTESGNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLITDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSTRISLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKSLIAIQLTGGSEHILKDNEIMFNRSVDQGYGVYLENTDKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>tr|A0A7U4HXJ2|A0A7U4HXJ2_BACIU Uncharacterized protein OS=Bacillus subtilis OX=1423 GN=KS08_10530 PE=4 SV=1 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYACSKSFYKVYVPKGIYLIDAVNT-SKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINEKEIKTYGIDSVGVSSTESGNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLFTDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSSRVSLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPDKYSCQISENQIYFCKSLIAIQLTGGSEHILKDNEIMFNRSADQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIYNTYDSGTLKTAEGDIVV--- +>tr|I2C5Q7|I2C5Q7_BACAM Uncharacterized protein OS=Bacillus amyloliquefaciens Y2 OX=1126211 GN=MUS_2014 PE=4 SV=1 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGGTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGVDSVGVSSTESGNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLITDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSTRISLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKSLIAIQLTGGSEHILKDNEIMFNRSVDQGYGVYLENTDKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>tr|A0A4V7TQN6|A0A4V7TQN6_BACAM Uncharacterized protein OS=Bacillus amyloliquefaciens OX=1390 GN=D2M30_2250 PE=4 SV=1 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGVYLIDAVNTA-KRLPEFGGGINVPSNIELILHPEAIFKVQPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKINAIQKTHEWGYGIHIHGSNNILIDGVHVSDCIGDNIWIAADGMMNTSG-VYTPSSSATVQKCTLLRGRRNNMATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGIDSVGVSSTESSNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLISDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSSRVSLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKSLIAIQLTGGSEHMLKDNEIMFNRSADQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIYNTYDSGTLKTAEGDIVV--- +>tr|A0A8B2V7S0|A0A8B2V7S0_BACAM Uncharacterized protein OS=Bacillus amyloliquefaciens OX=1390 GN=C3733_08035 PE=4 SV=1 +---------YFVDALNWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDSVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVLPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKINAIQKTHEWGYGIHVHGSSNVLIDGVHVSDCIGDNIWIAADGMMNTSGK-YTPSRSVTVQKCTLKRGRRNNLATSGCNGLLVDDCDIEEAGGDTIGPQLGIDLEGYGEDGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSDKVIIEGNYSDHVISYGYSTDVSIKNNKIINENQVKTYGIDSVGVSSTESGNRVQINGNTIRGFAIGVCVRGKGIDVTDNIFENITACPITTHEAEDVYISDNHIENSDCIQVQVRNSKDVRVTNNKGGNTTSSYAIKVMDSNRVSCAINEFANVNGGVYCERSQSVRLKGNDFFLNGSGYGIFWDKDSEMYMNRNEIHNPRNFAIKGTSEKYSCQISENQIYFCKSLIAIHLTGGSEHMLNNNEIMFNRSTDQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDVVV--- +>tr|A0A7T7ZAL2|A0A7T7ZAL2_9CAUD Tail spike OS=Bacillus phage 268TH004 OX=2801523 GN=13 PE=4 SV=1 +---------YELEIDRWGISSGGSNPIETTQGFNDAIQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIYIKNVFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLIRGRRNCLATNGCEGLLVDDCAIEDAGGEGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVESNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGIYWGVNSEVEAKGNTIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGVKLKNNSVEVTNDRGLTSSFYTEKSTDSLVVMNDYNKGVIKSHETDTV---- +>tr|A0A5J6T752|A0A5J6T752_9CAUD Tail spike OS=Bacillus phage 019DV004 OX=2601654 GN=11 PE=4 SV=1 +---------YELEIDRWGISSGGSNPIETTQGFNDAVQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTKTHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLVRGRRNCLATNGCEGLLVDDCAIEDAGGEGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVGNNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGTGMGIYWGINSEVEAKGNIIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKTHETDTV---- +>tr|A0A5J6T3Z8|A0A5J6T3Z8_9CAUD Tail spike OS=Bacillus phage 019DV002 OX=2601653 GN=11 PE=4 SV=1 +---------YELEIDRWGISSGGSNPIETTQGFNDAVQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTKTHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLVRGRRNCLATNGCEGLLVDDCAIEDAGGEGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVGNNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGTGMGIYWGINSEVEAKGNIIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKTHETDTV---- +>tr|A0A5J6T9J0|A0A5J6T9J0_9CAUD Tail spike OS=Bacillus phage 276BB001 OX=2601664 GN=12 PE=4 SV=1 +---------YELEIDRWGISSGGSNPIETTQGFNDAIQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TLYTPARDVTVSKCTLIRGRRNCLATNGCEGLLVDDCAIEDAGGEGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGALVESNTLENISAVAVQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGIYWGVNSEVEAKGNTIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKSHETDTV---- +>tr|A0A5J6T6D8|A0A5J6T6D8_9CAUD Tail spike OS=Bacillus phage 280BB001 OX=2601665 GN=12 PE=4 SV=1 +---------YELEIDRWGISSGGSNPIETTQGFNDAIQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TLYTPARDVTVSKCTLIRGRRNCLATNGCEGLLVDDCAIEDAGGEGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGALVESNTLENISAVAVQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGIYWGVNSEVEAKGNTIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKSHETDTV---- +>tr|A0A5P8PIC1|A0A5P8PIC1_9CAUD Tail spike OS=Bacillus phage 056SW001B OX=2601663 GN=11 PE=4 SV=1 +---------YELEIDRWGISSGGSNPIETTQGFNDAVQYAKSEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIHIKNAFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLVRGRRNCLATNGCEGLLVDDCAIEDAGGEGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKIIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVESNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGVYWGVNSEVEAKGNTIEVGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKSHETDTV---- +>tr|A0A5J6T5S7|A0A5J6T5S7_9CAUD Tail spike OS=Bacillus phage 031MP003 OX=2601657 GN=8 PE=4 SV=1 +---------YELECDRWGIFPDGTNPVETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYTGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNTYN---------------- +>tr|A0A5J6T527|A0A5J6T527_9CAUD Tail spike OS=Bacillus phage 031MP004 OX=2601658 GN=8 PE=4 SV=1 +---------YELECDRWGIFPDGTNPVETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYTGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNTYN---------------- +>tr|A0A5J6T6E0|A0A5J6T6E0_9CAUD Tail spike OS=Bacillus phage 022DV001 OX=2601655 GN=8 PE=4 SV=1 +---------YELECDRWGIFPDGTNPVETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYAGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTIVDGNKYN---------------- +>tr|A0A5J6T8J3|A0A5J6T8J3_9CAUD Tail spike OS=Bacillus phage 055SW001 OX=2601662 GN=8 PE=4 SV=1 +---------YELECDRWGISPDGTNPTETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYAGSTYITARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNKYN---------------- +>tr|A0A7U3TW25|A0A7U3TW25_9CAUD Minor tail protein OS=Bacillus phage 000TH009 OX=2801831 GN=222 PE=4 SV=1 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSTNVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>tr|A0A5J6T602|A0A5J6T602_9CAUD Tail spike OS=Bacillus phage 031MP002 OX=2601656 GN=7 PE=4 SV=1 +---------YELECDRWGISPDGTNPPETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYHEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYAGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTVEEAGG--VGPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGVVKPYGIDSLGVSSTETGNRASIKGNTIRGFNIGINAKGKGILVSKNTIEDVESVGIQVYQATSALVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLHTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNKYN---------------- +>tr|A0A7T8C426|A0A7T8C426_9CAUD Minor tail protein OS=Bacillus phage 000TH008 OX=2801830 GN=222 PE=4 SV=1 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSINVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>tr|A0A076G7N8|A0A076G7N8_9CAUD Tailspike protein OS=Bacillus phage Bobb OX=1527469 PE=4 SV=1 +---------YFIDFEKHGIRSNGTAARETTDGFISALNDAVASGYKTVYVPKGNYLIDGVG--EDKMPEYGGGIQFPSNIEVIFHKEAVFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMVSPFRRTHEWGYGVHIRGCRNILIEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTEKGRRNNIATDGCLGLLIDDCDIIKAGGDTIGPQLGIDLEGYAEDGIKYGHPYEINITNCRFRKNGRGALNINVSAKVHATNNFSDDVFSYGYSSDVSICNNKIINDSGTKKYGIDSIRKSSTETGNRAIISGNHVIGFEIGICARGLGVKISNNYLKDISSIGIYPYLAEEVSVSDN-IIDSNCLHVWVRESKDVKISDNKTKGAANYFAYRVEASSDV-IISDSKSQSKGGIQVLRSRKVVLKDNDLALIGTDYGIHWDKQSEVEVLHNTVRDAAMIAIAGNSELYPSIIKGNNIKDCTYLVGLYVNGGSDHILWDNDVSFTGSANGGYGVQLVGTENAWLMNNKVRVSNGRTLSSSYESRGSQNTMYINNALQTG-------------- +>tr|A0A7T7ZC39|A0A7T7ZC39_9CAUD Minor tail protein OS=Bacillus phage 015DV002 OX=2801832 GN=212 PE=4 SV=1 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KSGVRVSRSTNVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>tr|R4JDQ9|R4JDQ9_9CAUD SPBc2 prophage-derived protein YorA OS=Bacillus phage SIOphi OX=1285382 GN=SIOphi_00245 PE=4 SV=1 +---------YFIDFDQFGIKDDGTDATSTTSGFVAAFKRAVELGHSAVYVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGHIVGDRHEHNYRQVNENRRTHEWGFGIQVRGSKNVTIENVTIEDCTGDNIWVTSKGMMNWPG-VYIPSESVTIRKCRTLRGRRNNIAAGASVGLLIDDCDIIEAGGDEIGPQLGIDLEGYADNSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGHKKFGIDSIRKSTSETANRAVVTGNVIRGFQTGIAARGKTVTVSNNILEDISSIGIYPYLCDQAVVSSN-IIDSDCLHIWVRESKDIKVSDNKGTGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSTNVRIVDNDIDMIGPDYGIYFDKQSEVHLRDNLVKNAAFTAIRGYADQYSSYIKGNIIQDCKYMIAIHIDGGSKHMIKDNDITFRRGSNAGYGVYLIGANDSRLHNNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>tr|A0A7U3TFK2|A0A7U3TFK2_9CAUD Minor tail protein OS=Bacillus phage 015DV004 OX=2801833 GN=228 PE=4 SV=1 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQSNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSTNVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>tr|A0A5J6TBR2|A0A5J6TBR2_9CAUD Tail spike OS=Bacillus phage 035JT001 OX=2601659 GN=8 PE=4 SV=1 +---------YELECDRWGIFPDGTNPESTTRGFNDALTFAAAEGYKEIYIPKGVYKIDCVSRFGSK-PEYGGGIRNPSNLDVDMHTEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEDKTKTHEWGYGVHIRGSKNINIENMFISDCTGDNIWVAANGMMNYEGSTYIPSKDVTVRKCTLMRGRRNGLATNGCEGLLVDDCTIEESGGGGTRPEYGIDLEGFGEGGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRASIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSALVIGNRI-DADCTHIQMLYAEKTTVIGNESEGNTQNFAYKVTYSDRTVFSGNTLYDGDGGLDVGQSTLTKFKGNTLFLTGENFGVHWGSSSDLEVSGNTFHMGSGVAIFGYADLHTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKIARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSAGTLVDGNKYN---------------- +>tr|A0A2I6UI00|A0A2I6UI00_9CAUD Uncharacterized protein OS=Bacillus phage BSP10 OX=2069312 GN=BSP10_173 PE=4 SV=1 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALKDAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAKNYYGIKVEDSSDV-VVNDNKQVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKTSQVKLVKNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>tr|A0A890URD5|A0A890URD5_9CAUD Tailspike OS=Bacillus phage BSTP3 OX=2801528 GN=BSTP3_034 PE=4 SV=1 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALKDAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAKNYYGIKVEDSSDV-VVNDNKQVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKTSQVKLVKNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>tr|U5PXV9|U5PXV9_9CAUD Tailspike OS=Bacillus phage Grass OX=1406785 GN=Grass_33 PE=4 SV=1 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALKEAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFMVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTVPDNRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPAKGMMNWEGSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFSYGFSTDSTISNNTITNETGDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVQVGNNKGKDAENYYGIKVEDSSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKTSQVKLIKNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>tr|S6BUP9|S6BUP9_9CAUD Beta_helix domain-containing protein OS=Bacillus phage phiNIT1 OX=207656 GN=orf587 PE=4 SV=1 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALREAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAENYYGIKVEDSSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKISQVKLVKNWISCAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>tr|A0A384XD57|A0A384XD57_9CAUD Uncharacterized protein OS=Bacillus phage BSP9 OX=2041339 GN=BSP9_162 PE=4 SV=1 +----NSNYMYFVDFEKFGIRSDGTEARATTEGWIAALKEAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAENYYGIKVEASSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKISQVKLVKNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>tr|L0L8C8|L0L8C8_9CAUD Putative Pectin lyase-like protein OS=Bacillus phage phiAGATE OX=1204533 PE=4 SV=1 +---------YFIDFEKHGIKSDGTAARETTDGFTYALNDAVNKGYKTVYVPKGDYLINGVG--EDRMPEYGGGIQFPSNIEVIFHKKAIFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMVSKFRKTHEWGYGVHIRGSRNILVEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTERGRRNNIATDGCLGLLIDDCDIIEAGGDTIGPQLGIDLEGFAEDGIKYGHPYEINVVNNRIRNNGRGSLNINVSAKVHASNNFSDDVFSYGYSSDVSICNNKIINDSGKRKYGIDSIRKSSTETGNRAIITGNHIIGFEIGICARGLGVKIANNYLKDISSIGIYPYLAEEVSVSDN-IVDSNCLHVWVRESKDVKISDNKTKGADNDFAYRVESSSDV-IISDSKSQANGGIQVIRSRKVTLKDNDLTLTGADYGIYWDKQSEVEVLHNTVRDAAMIAIAGNSNLYPSIVKGNNIKDCTYLVGLYMNGGRDHVIWDNDVSFKGSSNGGYGVQLIATTNAWLMDNKVRVSNGRTLSSAYESQSSYKTLYVNNAMQIG-------------- +>tr|A0A1Z1DEW7|A0A1Z1DEW7_9CAUD Tailspike protein OS=Bacillus phage vB_BsuM-Goe3 OX=1933063 GN=Goe3_c03000 PE=4 SV=1 +----NSKYVYDIDFGKFGIKPDCTEAAATTEGFITALEDAVDQGYPKVYIPEGFYLIDAVGT-SGKLPEFGGGLRFPSNIEVIFHEKAVFIVDPNDATGYACFNLENVENVTLRGGVVIGDRYKHTYEGVPDNRKTHEWGYGLQIRGCRNIKVENMTLMDATGDNIWVPAKGMMNWEGSTYIPSEGITIDKCYTLRGRRNNLATNGCLGLNINDCDFVEAGGDTIGPAYGIDLEGFAENSIKYDHPYEINVTNCRFKRNGKGALTINVAGKAHATNNFSDDIISYGFSTDATISNNTITNESEEKEYGIDSIRKSSSETGNRAIITGNHIRGFKSGICARGVGVVASNNYLENISSVGIYAYLAKNVLMADNVI-NSDCLHVWVRESEDVKISNSKGKGAINNWGIKVEASSNVS-LNDNEHDSKGGVQVARSTDVRAWDNRFTLVGNEYGAYWDKTSEVVFEGNHIFNPSTIAIAGYGDTYASSIVRNTIHDCKYLTAIYLSGGSQHFVKGNDIRFRRGANGGYGIKLTGTSGVKVIGNDVRTMDGCSLNASYDSSGSVNTQYANNTYHTG--RMLLHD------ +>tr|A0A516KNA2|A0A516KNA2_9CAUD Putative pectin lyase OS=Bacillus phage vB_BveM-Goe7 OX=2593639 GN=Goe7_c00300 PE=4 SV=1 +----NSKYVYDIDFGKFGIKPDCTEAAATTEGFITALEDAVDQGYPKVYIPEGFYLIDAVGT-SGKLPEFGGGLRFPSNIEVIFHEKAVFIVDPNDATGYACFNLENVENVTLRGGVVIGDRYKHTYEGVPDNRKTHEWGYGLQIRGCRNIKVENMTLMDATGDNIWVPAKGMMNWEGSTYIPSEGITIDKCYTLRGRRNNLATNGCLGLNINDCDFVEAGGDTIGPAYGIDLEGFAENSIKYDHPYEINVTNCRFKRNGKGALTINVAGKAHATNNFSDDIISYGFSTDATISNNTITNESEEKEYGIDSIRKSSSETGNRAIITGNHIRGFKSGICARGVGVVASNNYLENISSVGIYAYLAKNVLMADNVI-NSDCLHVWVRESEDVKISNSKGKGAINNWGIKVEASSNVS-LNDNEHDSKGGVQVARSTDVRAWDNRFTLVGNEYGAYWDKTSEVVFEGNHIFNPSTIAIAGYGDTYASSIVRNTIHDCKYLTAIYLSGGSQHFVKGNDIRFRRGANGGYGIKLTGTSGVKVIGNDVRTMDGCSLNASYDSSGSVNTQYANNTYHTG--RMLLHD------ +>tr|A0A345MJP4|A0A345MJP4_9CAUD NosD domain-containing protein OS=Bacillus phage BSP38 OX=2283013 GN=BSP38_034 PE=4 SV=1 +----NSKYVYFVDFEKFGIKSDGTDAAATTSGWIAALKEAVDLGYPKVYVPAGLYLIDAVGKTDSL-PEYGGGLRFPSNIEVIFHEMALFKVEPNSSTGYACFNLENVENVTLRGGYVIGDRYEHDYTLVPNNRRTHEWGHCLHIRGCRNIYVENMTLMNATGDNIWVPAKGMMNWEGSTYIPSEGITIHKCTTIRGRRNNFATNGCIGLNIDDCDFIEAGGDVIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFTDDVISYGFSTDGTISNNTITNETGHKPFGIDSIRKSSSETGNRTIITGNQIRGFASGICARGVGVIVSNNYLSDISSVGIYPYLSEEVLVSNN-IINSDCLHVWVRESKDVKVNNTKGKGAANNYGIKVEASHDV-VLNDNEHEAKGGIQIARSTNVRVKDNDLNLIGNGNGISWDKTSQVILDGNWINGAVAIAISGYGEVYPTNIMRNTIEDCKYLIGIYLNGGSQHVIKDNDIMFRRGSNGGYGVQLKDTTDVRVYRNDVRTMDGGTLYSSFDSSGALSTKYVGNTMDAG-------------- +>tr|A0A5B9NKS7|A0A5B9NKS7_9CAUD Putative right-handed parallel beta-helix repeat-containing protein OS=Bacillus phage vB_BspS_SplendidRed OX=2591379 GN=SPLENDIDRED_11 PE=4 SV=1 +---MNKELYYHIDLERFGIRDDLTEANATTQGFNAALKDAKEQGYHYFVFPEGKYLINTISNFGGL-PEYGGGIRIPSNIHIIMD-NPYFEAEANDRTGYSIFYLEAVENVEISGGTICGDRYNHDYDLKDDRTKTHEWGFGIHIRGCRRVAIKGLTVKNCTGDNIWIPAKGMMNFPG-DYTPSRDILIQDCDLIHGRRNNLATNGCYGLTVERCDIKEAGGDTIGPQLGIDLEGYGDKGIKYDHPYEITIKNNWIKNNGRGALTAHTSGKVLIEGNFTDAVISYAYSTDVKIKDNFIINEGQEKPYGIDSIGVSSSETANRVNISGNTVSGFKTGICARGSKVKVRNNEVEGATAAAIQIFQCEKAEVSDN-TTDGNAVGLLIQQSKTVEASDNTFRGAENKYGIKIQDSSDIILKDNRIRG-FGGIFCESVQNVVVRDHDINLTGSGYGVYFDAKSCVFLDGVTIYNPENTSVYGLADEYAAIIKGVEVIGCKSIIGIYLHGGINHDIKGNTVRFKRGKDQGYGIYLDGTKGAVLARNDVVSTDGFKLSAAYKTDESEQTTLIEN------------------- +>tr|A0A386K842|A0A386K842_9CAUD Uncharacterized protein OS=Bacillus phage Ray17 OX=2315627 GN=Ray17_11 PE=4 SV=1 +---MSKGLYYHIDLERFGIKDDLTEANATTQGFNAALKDAKDQGYHYFVFPEGKYLINAVSNFGGL-PEYGGGIRIPSNINIIMD-NPYFEAEANDQTGYSIFYLEAVENVKISGGTICGDRYNHDYDLKDDRTKTHEWGFGIHIRGCRRVEIKGLTVKNCTGDNIWIPAKGMMNWP-TDYTPSRDILIQDCDLIQGRRNNLATNGCYGLTVERCDIKEAGGDTIGPQLGIDLEGYGDKGIKYDHPYEITIKNNWIKNNGRGALTAHTSGKVLIEGNFTDAVISYAYSTDVKIKDNFIINEGQEKPYGIDSIGVSSSETANRVNISGNTVSGFKTGICARGSKVKIHGNEVEGATAAAIQIYQCEKVEVSDN-TTDGNAVGLLIQQSKTVEASDNTFRGSENKYGIKIQDSSDIILKDNRIRG-FGGIFCESAQKVIVRDHDIDLTGSGYGVYFDAKSSVFLDGVTIYNPENTPVYGLADEFAAIMKDVEVIGCKSIIGIYMHGGFGHDIKGNTVRFRRGKDQGYGIFLDGTKSAVLTRNDVLSTDGFKLSAAYKTDGSERTTLIEN------------------- +>tr|D0VXF4|D0VXF4_9CAUD Beta_helix domain-containing protein OS=Bacillus phage phiNIT1 OX=207656 PE=4 SV=1 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALREAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALTSTLQGKFMLLIT-SPMMAQLWFSTDSTISNNTITNETGDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAENYYGIKVEDSSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKISQVKLVKNWISCAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>tr|A0A0A0PLR7|A0A0A0PLR7_9CAUD Putative pectin lyase-like protein OS=Bacillus phage Bp8p-T OX=1445811 GN=Bp8pT_172 PE=4 SV=1 +-------------------------------------------------------------------PEYGGGIQFPSNIEVIFHKEAVFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMVSKFRKTHEWGYGVHIRGCRNILVEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTERGRRNNIATDGCLGLLIDDCDIVEAGGDTIGPQLGIDLEGFAEDGIKYGHPYEINITNNRFRENGRGSLNINVSAKVHATNNFSDDVFSYGYSSDVSICNNKIINESGKRKYGIDSIRKSSTETGNRAIITGNHIIGFEIGICARGLGVKIANNYLKDISSIGIYPYLAEEVSVSDN-IIDSNCLHVWVRESKDVKISDNKTKGAANHFAYRVEASSDV-LISDSKSQSKGGIQVIRSRKVILKDNDLSLTGADYGIQWDKQSEVEVLNNTVRDAAMIAIAGNSELYPSVIKGNNIKDCTYLVGLYVNGGSNHILWDNDISFTGTTNGGYGVQLVGTENVWLMNNKVRTSNGRLLSSAYESRNSKKTMYINNALQAG-------------- +>tr|A0A0A0PUI4|A0A0A0PUI4_9CAUD Putative pectin lyase-like protein OS=Bacillus phage Bp8p-C OX=1445810 GN=Bp8pC_172 PE=4 SV=1 +-------------------------------------------------------------------PEYGGGIQFPSNIEVIFHKEAVFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMVSKFRKTHEWGYGVHIRGCRNILVEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTERGRRNNIATDGCLGLLIDDCDIVEAGGDTIGPQLGIDLEGFAEDGIKYGHPYEINITNNRFRENGRGSLNINVSAKVHATNNFSDDVFSYGYSSDVSICNNKIINESGKRKYGIDSIRKSSTETGNRAIITGNHIIGFEIGICARGLGVKIANNYLKDISSIGIYPYLAEEVSVSDN-IIDSNCLHVWVRESKDVKISDNKTKGAANHFAYRVEASSDV-LISDSKSQSKGGIQVIRSRKVILKDNDLSLTGADYGIQWDKQSEVEVLNNTVRDAAMIAIAGNSELYPSVIKGNNIKDCTYLVGLYVNGGSNHILWDNDISFTGTTNGGYGVQLVGTENVWLMNNKVRTSNGRLLSSAYESRNSKKTMYINNALQAG-------------- +>tr|A0A5P8PIG3|A0A5P8PIG3_9CAUD Uncharacterized protein OS=Bacillus phage 049ML003 OX=2601661 GN=42 PE=4 SV=1 +---------YPVNLEEWGINKDFQEPEATTEAFNKAFTYAKNMGYFEVWVPPGNYLIDGVNESNIYATENGGGIHLHSNTHYKLNPESVFKINANNAQGYSVFYIGLAYNVTLEGGQLIGDRHEHDYSTVTQNRNTHEFGFGVNVHGSERVNIVNVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDVIGPQLGIDFEGYAENGIKYAHPYNLQLKNSRFRDNGRGCFTAHAVGKAIISENFFDDRVSYGFGTDISIVDNHIINDGEVRDLAIDSIQPPSYDNANRVKISGNKIKGFKKGMTIRGKEIDVTDNDLNNITETGIHVYLAEEITVNENRV-NSDCVPLNIQISKKVNVSDNTFKGGAEKYGVIVSEVEDISFKDNHI-EAGGGIDAGSAKNVRISKNEIFVKGKLNALRNNAGSTVKVNGLNIYDPAAYPMAGALDIKNV-----SIYGCKAFIAINIKNGRRHKIKNNDIVFERETNGGYGVYLSGTERTKLMDNDVSTSNDFAIGAPFHTEGSMYSTIMHNYYDSG-------------- +>tr|M4ZRV1|M4ZRV1_9CAUD Beta_helix domain-containing protein OS=Bacillus phage PM1 OX=547228 PE=4 SV=1 +---------YPLNLEEWGINKEFQEPEETTAAFNKAFEYAKSMGYFKILVPPGNFLIDGVNESNIYATENGGGIHLHSNTHYLLHPESVFKINANDAQGYSVFYIGLAYNVTLEGGQLIGDRHEHDYSTSTQNRNTHEFGFGVNVHGSERVNIINVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDTIGPQLGIDFEGYAENGVKYAHPYNLQVKDSRFKNNGRGCFTAHAVGKAIISKNFFDDRVSYGFGTDISIVDNHIINDGEVRPLAIDSIQPPSYDNANRVKISGNTIKGFKKGMTIRGKEVDVIDNKLNNITDTGIHVYLAEEITVNENRV-NSDCVPLNIQISEKVNVSDNTFKGGSEKYGVVISEVEDISFKDNHI-EAGGGIDAGVAKNVRISKNEIFVKGKLNALRNNAGSTVKVNGLNIYDPAPMELDGSAGALDIR--NVSIYGCKAFIAINIKNGKSHKIKNNDIIFNRGSNGGYGIHLSGTEKAKLTNNYVSTSDGFAIGSPYHTENSTYSTVMNNYYDSG-------------- +>tr|A0A5P8PHR1|A0A5P8PHR1_9CAUD Beta_helix domain-containing protein OS=Bacillus phage 000TH010 OX=2601652 GN=49 PE=4 SV=1 +---------YPVNLEEWGINKDFQEPEATTEAFNRAFTYAKNMGYFEVWVPPGNYLIDGVNESNVYATENGGGIHLHSNTHYKLNPESVFKINANDAQGYSVFYVGLAYNVTLEGGQLIGDRYEHNYSTVAPNRSTHEFGFGVNVHGSERVNIINVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDIIGPQLGIDFEGYAENGIKYAHPYNLQLKNSRFKDNGRGCFTAHATGKAIISENFFDDRVSYGFGTDISIVDNHIINDGEVRPLAIDSIQPPSYDNANRVKVAGNKIKGFKKGMTIRGKEVDVTDNDLNDVTETGIHVYLAEEITVNENRV-NSDCVPLNIQISKKVNVSDNTFKGGAEKYGVVISEVEDISFKDNHI-EAGGGIDAGSAKNVRISKNEIFVKGKLNALRNNPGSTMKVNGLNIYDPAAYPMELDGSAGSLDIKNVSIYGCKAFIAINIKNGRRHKIKNNDIIFERETNGGYGIYLSGTERTKLMDNDVSTSNDFAIGSPFHTENAMYSTIMHNYYDSG-------------- +>tr|A0A5P8PI75|A0A5P8PI75_9CAUD Beta_helix domain-containing protein OS=Bacillus phage 049ML001 OX=2601660 GN=42 PE=4 SV=1 +---------YSVNLEEWGINKDFQEPEATTEAFNKAFTYAKNMGYFEVWVPPGNYLIDGVNESNIYATENGGGIHLHSNTHYKLNPESVFKINANNAQGYSVFYIGLAYNVTLEGGQLIGDRHEHDYSTVTQNRNTHEFGFGVNVHGSERVNIVNVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDVIGPQLGIDFEGYAENGIKYAHPYNLQLKNSRFRDNGRGCFTAHAVGKAIISENFFDDRVSYGFGTDISIVDNHIINDGEIRALAIDSIQPPSYDNANRVKISGNKIKGFKKGMTIRGKEIDVTDNDLNNITETGIHVYLAEEITVNENRV-NSDCVPLNIQISKKVNVSDNTFKGGAEKYGVIVSEVEDISFKDNHI-EAGGGIDAGSAKNVRISKNEIFVKGKLNALRNNPGSTVKVNGLNIYDPAAYPMAGALDIKNV-----SIYGCKAFIAMNIKNGRRHKIKNNDIVFERETNGGYGVYLSGTERTKLTDNDVSTSNDFAIGAPFHTEGSMYSTIMYNYYDSG-------------- diff --git a/test/unit/data/uniprot.mode5.txt b/test/unit/data/uniprot.mode5.txt new file mode 100644 index 00000000..8e8d2208 --- /dev/null +++ b/test/unit/data/uniprot.mode5.txt @@ -0,0 +1,120 @@ +>O31912 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A6H0H3G5 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A162RH73 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A6M4JNF4 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>O64135 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>O31912 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A857HHC0 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFPIVEVPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGGSKEYGIDSVGVSSTETGNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSAYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVKGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGARVLSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A410R1H8 +MTLLNKSIRYYVDFDQWGINAFNSNPIETTKGFNEALIYASENNFSIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNTELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGVSSTETSNRIQITDNNIQGFKIGMMIRGKGVSVDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSTYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGTRVLSHPYATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A7G5CIE1 +MTLLNKSIRYYVDFDQWGINAFNLNPIETTKGFNEALIYASENNFPIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGFSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVCNNKGKGTTSTYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYFNGTKKVRLIRNDVQGIGTRVLSHPYATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A7G5CIX1 +MTLLNKSIRYYVDFDQWGINAFNLNPIETTKGFNEALIYASENNFPIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGFSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVCNNKGKGTTSTYAIKVMDSNDVKFLNNTFSNLYGGLYCERSQAVRIKLNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYFNGTKKVRLIRNDVQGIGTRVLSHPYATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>G4EVD8 +MTLLNKSIRYYVDFDQWGINAFNLNPIETTKGFNEALIYASENNFPIVEIPKGNFIIDSVNTLNQRNPEIGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGRIIGDRYQHDYSLIDTNRKTHEWGFGIHVHGSKNVLIENVQISDCIGDNIWIAAHGMMNYPGMVYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGFSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVCNNKGKGTTSTYAIKVMDSNDVTFINNKFSNLYGGLYCERSQSIRIKQNDFLLSGKGYGIYWDKDSKVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIMFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGSRILSHPFATFNASSTTLIHNTYDSGTPRLALDDTVIDYK +>A0A7G5CHW7 +MILLNKSMRYYVDFDQWGINAFNSNPNETTKGFNEALIYASKNNFPIVEIPKGNFIIDSVNTLNQRNPEVGGGIKIPSNMELLLDPEAVFQVNPNGYQGYSCFYIGLAENVIIRGGHIIGDRYQHDYSLIDTDRKTHEWGFGIHVHGSKNVLIENVKISDCIGDNIWIAAHGMMNYPGMAYTPSKSVTVRKCELKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGYGENGRKYDHPYELTISDCRFRKNGRGSVTAHTSGKVSIKDNYCDNVISYGYSTDVSIKGNKIINEGESKEYGIDSVGVSSTETSNRIQITDNNIQGFKIGMMIRGKGVSIDNNTVKNASNCAIATHMAEDVSISNNRIQDSDCIQIQVRNSSDIKVSNNKGKGTTSTYAIKVMDSNDVTFINNKFSNLYGGLYCERSQSIRIKKNDFLLSGKGYGIYWDKDSEVFLTRNEIFEPRNVAIMGAADMYNIRISDNQIYNCKAIIAIHLIGGSEHMVRGNEIVFNRDSDQGYGIYLNGTKKVRLIRNDVQGIGSRILSHPFATFNASSTTLIHNTYDSGTPRLALDDTLIDYK +>A0A837Y204 +MNMIDKSLRVHVDFEQWGINPEGLNPIETTKGFNDALQSAASNFYSVVEVPKGNYLIDAVNT-SKRLPEFGGGIKIPSNIELILHPEAVFRVNPNGYQGYSCFYIGQAENVTIRGGRIIGDRYEHDYSKINTIQKTHEWGYGIHVHGSRNVLIENVSVSDCIGDNIWIAADGMMN-TDVTYTPSRSVTVRKCRLKRGRRNNLATNGCEGLLVEDCDIEEAGGDTIGPQLGIDLEGFAEKGIKYDHPYELTIADCRFKKNGRGSITAHTSGKVIIKDNYCDNVISYGFSTDVSIKGNKIINEGEPKEYGIDSIGVSSTETGNRAKITGNTVRGFKIGIMVRGRGVTAKNNTIGNSSNCAIATHTAEEVFIAKNKIENSNCIQIQVRNSSDVKVNGNTGKGTTSSYALKVIDSKDVTLTGNEFSNIYGGLYCERSQAVRVKSNDFLMRGTGYGIYWDKSSEVFLTRNEIYEPRNIAITGTADIYNIRISENQIYNCKALVAIHLLGGSDHMLRGNEIMFNREADQGYGIYLESTKKVRLIRNDVQGIGDRVLSHPYATFKSSNTTLIHNTYNSGTLRLAVDDIVI--- +>A0A150FBD2 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGFNRALEYASSNSFFRVYVPKGKYLIDAVNT-TKRLPEFGGGIYVPSNIELILHPEAVFHVLPNDYQGYSCFYVGQASNVTIRGGQIIGDRYEHDYSKINSTQETHEWGYGIHIHGSKNVLIENVSISDCIGDNIWIAAYGMMNTSG-TYTPSRNVTVRKCTLKRGRRNNLATNGCEGFLVDDCDIEEAGGDTIGPQLGIDLEGFGEKGIKYDHPYKLTVRNCRFKNNGRGSITAHTSGKVIIDGNYCDNVISYGYSTDVSIKNNKIINEGSVKTYGIDSVGVSTTESGNRVQIDGNTVSGFEVGICARGKGVTISNNTLERIKACPISTHQAEDVLITDNRMENSDCIQVQVRNSNDVRVVNNKGKGTTTAYASKIMDSTRVSLINNEFVNVYGGVYCERSQSVRLKGNDLILSGSGHGIFWDKDSSVSLHRNEIHEPKNVAIKGTPEKYSCQISENQIYFCKSLIAIHLVGGSEHILKDNEIMFNRSSDQGYGVYLENTNKARLVRNDVHGIGGKLLSHPYCTEKAKNTTLIHNTYNSGTLKTAEGDTIV--- +>A0A109WGG2 +---MRQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKISAIQKTHEWGYGIHVHGSSNVLIENVQVSDCIGDNIWIAAEGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGEVNLEGNYSDNVISYGYSTDVSVKDNKIINKGKSKKYGIDSVGVSSTESGNRVQIIGNTVRGFEIGICVRGKGVHVADNILENITACPIATHEAEDVFISNNHIENSDCIQVQVRNSKDVRVTNNKGGNTTSAYAIKIMDSNRVSFAINEFANVHGGVYCERSQSVRLKLNDLFLSGSGYGIFWDKDSEVYFNGNEIHNPRNVAIKGTSEKYSCQISENQIYFCKSLIAIHLAGGSEHMLNNNEIMFNRSTDQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>A0A8A5UUR4 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNITVRKCALLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGEVNLEGNYSDNVISYGYSTDVSVKDNKIINKGNSKKYGIDSVGVSSTESGNRVQISGNTVRGFEIGICVRGKGIDVTDNILENISACPIATHEAEDVFISNNHIENSDCIQVQVRNSKDVRVTNNKGGNTTSAYAIKIMDSNRVSFAINEFANVHGGVYCERSQLVRLKLNDLFLGGSGYGIFWDKDSEVYFNGNEIHNPRNVAIKGTSEKYSCQISKNQIYFCKSLIAIHLTGGSEHMLNNNEIMFNRSTDQGYGVYLENTNKVRLVRNDTRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>A0A4R2A540 +---MQQPLYYSVDALDWGIDDKGSNAIETTEGINRALKYASSKSFYKVHIPKGTYLIDAVNT-SRRLPEFGGGINIPSNIELILHPEAVFKVLPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKVTSIKRTHEWGYGIHIHGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGQVIIEGNYSDNVISYGFSTDVSIKNNKIINDAETKKYGIDSVGVSSTESGNRVQIEGNTVRGFEIGICARGKGVLISNNTLEGIKTCPIATHQAEDVLITDNRIENSDCIQVQVRNSNDVRVVNNKGKGTISAYAVKIMDSTRISLINNEFVNVYGGIYCERSQSVRLKGNDLLLNGSGYGIFWDKDSSVSLQRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKALIAIQLTGGSEHMLKDNEIMFNRSTDQGYGVYLENTDKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>A0A853LAC0 +---MQQPLFYFVDAQDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGTYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIKEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIDGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGIDSVGVSSTESGNRVQIDGNTISGFEVGICVRGQGGTVSNNTLEKIKACPIATHQAEDVLITDNRIENSDCIQVQVRNSNDIRVVNNKGKGTTSAYAAKIMDSTRISLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPDKYSCQISENQIYLCKSLIAVQLTGGSEHILKDNEIMFNRSADQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIYNTYDSGTLKTAEGDIVV--- +>S6FH05 +---MQQPLYYSVDALDWGIDDKGSNAIETTEGINRALKYASSKSFYKVHIPKGTYLIDAVNT-SRRLPEFGGGINVPSNIELVLHPEAIFKVLPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKVTSIKRTHEWGYGIHIHGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGQVIIEGNYSDNVISYGFSTDVSIKNNKIINDAEVKKYGIDSVGVSSTESGNRVQIEGNTVRGFEVGICARGKGVSISNNTLEGIKACPIATHQAEDVLITDNRIENSDCIQVQVRNSNDVRVVNNKGKGTISAYAVKIMDSTRISLINNEFVNVYGGIYCERSQSVRLKGNDLLLNGSGYGIFWDKDSSVSLQRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKALIAIQLTGGSEHILKDNEIMFNRSTDQGYGVYLENTDKVRLVRNDARGIGGKLLSHPYCTDKAKNTTLIHNTFDSGTLKTAEGDIVV--- +>A0A6H3B795 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGVDSVGVSSTESGNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLITDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSTRISLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKSLIAIQLTGGSEHILKDNEIMFNRSVDQGYGVYLENTDKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>A0A7U4HXJ2 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYACSKSFYKVYVPKGIYLIDAVNT-SKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINEKEIKTYGIDSVGVSSTESGNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLFTDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSSRVSLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPDKYSCQISENQIYFCKSLIAIQLTGGSEHILKDNEIMFNRSADQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIYNTYDSGTLKTAEGDIVV--- +>I2C5Q7 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDAVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVQPNDYQGYSCFYIGQASNVTIRGGQIIGDRHEHDYSKITSIKKTHEWGFGIHVNGSSNVLIENVQVSDCIGDNIWIAADGMMNTSG-TYTPSKNVTVRKCTLLRGRRNNLATNGCEGLLVDDCDIEEAGGGTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGVDSVGVSSTESGNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLITDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSTRISLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKSLIAIQLTGGSEHILKDNEIMFNRSVDQGYGVYLENTDKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDIVV--- +>A0A4V7TQN6 +---MQQPLYYFVDALDWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGVYLIDAVNTA-KRLPEFGGGINVPSNIELILHPEAIFKVQPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKINAIQKTHEWGYGIHIHGSNNILIDGVHVSDCIGDNIWIAADGMMNTSG-VYTPSSSATVQKCTLLRGRRNNMATNGCEGLLVDDCDIEEAGGDTIGPQLGIDLEGFGENGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSGKVIIEGNYSDHVISYGYSTDVSIKNNKIINENEIKTYGIDSVGVSSTESSNRVQIDGNTISGFEVGICVRGKGGTVSNNTFEKIKACPIATHQAEDFLISDNRIENSDCVQVQVRNSNDIKVVNTKGKGTSSSYAAKIMDSSRVSLVNNEFANVYGGIYCERSQSVRLKGNDLLLSGSGYGIFWDKDSSVSLHRNEIHEPRNVAIKGTPEKYSCQISENQIYFCKSLIAIQLTGGSEHMLKDNEIMFNRSADQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIYNTYDSGTLKTAEGDIVV--- +>A0A8B2V7S0 +---------YFVDALNWGIDDKGSNAIETTEGLNRALEYASSKSFYKVHIPKGIYLIDSVNT-TKRLPEFGGGINVPSNIELILHPEAIFKVLPNDSQGYSCFYIGQASNVTIRGGQIIGDRYEHDYSKINAIQKTHEWGYGIHVHGSSNVLIDGVHVSDCIGDNIWIAADGMMNTSGK-YTPSRSVTVQKCTLKRGRRNNLATSGCNGLLVDDCDIEEAGGDTIGPQLGIDLEGYGEDGIKYDHPYKLTVRNCRFKNNGRGSVTAHTSDKVIIEGNYSDHVISYGYSTDVSIKNNKIINENQVKTYGIDSVGVSSTESGNRVQINGNTIRGFAIGVCVRGKGIDVTDNIFENITACPITTHEAEDVYISDNHIENSDCIQVQVRNSKDVRVTNNKGGNTTSSYAIKVMDSNRVSCAINEFANVNGGVYCERSQSVRLKGNDFFLNGSGYGIFWDKDSEMYMNRNEIHNPRNFAIKGTSEKYSCQISENQIYFCKSLIAIHLTGGSEHMLNNNEIMFNRSTDQGYGVYLENTNKVRLVRNDVRGIGGKLLSHPYCTDKAKNTTLIHNTYDSGTLKTAEGDVVV--- +>A0A7T7ZAL2 +---------YELEIDRWGISSGGSNPIETTQGFNDAIQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIYIKNVFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLIRGRRNCLATNGCEGLLVDDCAIEDAGGEgGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVESNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGIYWGVNSEVEAKGNTIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGVKLKNNSVEVTNDRGLTSSFYTEKSTDSLVVMNDYNKGVIKSHETDTV---- +>A0A5J6T752 +---------YELEIDRWGISSGGSNPIETTQGFNDAVQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTKTHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLVRGRRNCLATNGCEGLLVDDCAIEDAGGEgGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVGNNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGTGMGIYWGINSEVEAKGNIIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKTHETDTV---- +>A0A5J6T3Z8 +---------YELEIDRWGISSGGSNPIETTQGFNDAVQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTKTHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLVRGRRNCLATNGCEGLLVDDCAIEDAGGEgGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVGNNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGTGMGIYWGINSEVEAKGNIIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKTHETDTV---- +>A0A5J6T9J0 +---------YELEIDRWGISSGGSNPIETTQGFNDAIQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TLYTPARDVTVSKCTLIRGRRNCLATNGCEGLLVDDCAIEDAGGEgGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGALVESNTLENISAVAVQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGIYWGVNSEVEAKGNTIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKSHETDTV---- +>A0A5J6T6D8 +---------YELEIDRWGISSGGSNPIETTQGFNDAIQYAKTEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIHIKNVFVADCTGDNIWIAAHGMMNWT-TLYTPARDVTVSKCTLIRGRRNCLATNGCEGLLVDDCAIEDAGGEgGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKVIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGALVESNTLENISAVAVQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGIYWGVNSEVEAKGNTIEAGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKSHETDTV---- +>A0A5P8PIC1 +---------YELEIDRWGISSGGSNPIETTQGFNDAVQYAKSEGYAEIFVPKGHYLIDCVSKFGSR-PEYGGGIRLVSDLNVTLHPEATFKVLANDATGYSLFYLELIENVTIKGGRIYGDRYEHTYTYYNDNTETHEWGYGIHVRGSRNIHIKNAFVADCTGDNIWIAAHGMMNWT-TPYTPARDVTVSKCTLVRGRRNCLATNGCEGLLVDDCAIEDAGGEgGTRPQYGIDLEGFGESGIKYDHPYKLVVRNCKFKGNALGDISSFTAGKIIIEGNTCENVISYGYSTDILIENNLIINEGEVKPYGIDSLGVSSTETGNRATIKGNTIRGFNIGINAKGKGVLVESNTLENISAVAIQVYQATDALIANNRV-DSDCIHFQALLAENTLFAGNKSEGNSKDYAYKITNSKGITFTGNELTEGYGGYYVQGSLRSKIISNTLQLVGAGMGVYWGVNSEVEAKGNTIEVGSGVPIMGYADLYKAIIKDNTVKGCQAVYAVYLKGGKRHNIESNILEIARNADYGYGVYIEGTSGAKLKGNSVEVTNDRGLTSSFYTEKSTGSLVVMNDYNKGVIKSHETDTV---- +>A0A5J6T5S7 +---------YELECDRWGIFPDGTNPVETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYTGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGgtrPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNTYN---------------- +>A0A5J6T527 +---------YELECDRWGIFPDGTNPVETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYTGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGgtrPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNTYN---------------- +>A0A5J6T6E0 +---------YELECDRWGIFPDGTNPVETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYAGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGgtrPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTIVDGNKYN---------------- +>A0A5J6T8J3 +---------YELECDRWGISPDGTNPTETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYAGSTYITARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTIEEAGG--VGgtrPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRVSIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSSLVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLYTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNKYN---------------- +>A0A7U3TW25 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQdVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGvHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSTNVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>A0A5J6T602 +---------YELECDRWGISPDGTNPPETTKGFNDALNYAAAEGYREIYIPKGVYKIDCVSNFGSR-PEYGGGIRNPSNLDVDMHPEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYHEEKTKTHEWGYGIHIRGSKNINIENVFVSDCTGDNIWIAANGMMNYAGSTYIPARDVTIKKCTLMRGRRNCLATNGCEGLLVDDCTVEEAGG--VGgtrPEYGIDLEGFGENGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGVVKPYGIDSLGVSSTETGNRASIKGNTIRGFNIGINAKGKGILVSKNTIEDVESVGIQVYQATSALVIGNRI-DADCTHIKMLYAKKTTVIGNESEGNTDNFAYQVTYSERTVFSGNTLYDGDGGLSVGNSTLTKFKGNTLFITGENYGVHWDASSDLEVSDNTFHMGSGVAIMGYADLHTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKVARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSVGTLVDGNKYN---------------- +>A0A7T8C426 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQdVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGvHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSINVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>A0A076G7N8 +---------YFIDFEKHGIRSNGTAARETTDGFISALNDAVASGYKTVYVPKGNYLIDGVG--EDKMPEYGGGIQFPSNIEVIFHKEAVFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMnVSPFRRTHEWGYGVHIRGCRNILIEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTEKGRRNNIATDGCLGLLIDDCDIIKAGGDTIGPQLGIDLEGYAEDGIKYGHPYEINITNCRFRKNGRGALNINVSAKVHATNNFSDDVFSYGYSSDVSICNNKIINDSGTvKKYGIDSIRKSSTETGNRAIISGNHVIGFEIGICARGLGVKISNNYLKDISSIGIYPYLAEEVSVSDN-IIDSNCLHVWVRESKDVKISDNKTKGAANYFAYRVEASSDV-IISDSKSQSKGGIQVLRSRKVVLKDNDLALIGTDYGIHWDKQSEVEVLHNTVRDAAMIAIAGNSELYPSIIKGNNIKDCTYLVGLYVNGGSDHILWDNDVSFkgTGSANGGYGVQLVGTENAWLMNNKVRVSNGRTLSSSYESRGSQNTMYINNALQTG-------------- +>A0A7T7ZC39 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQdVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGvHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KSGVRVSRSTNVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>R4JDQ9 +---------YFIDFDQFGIKDDGTDATSTTSGFVAAFKRAVELGHSAVYVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQPNDSTGYACFNLEGVENVTIRGGHIVGDRHEHNYRQdVNENRRTHEWGFGIQVRGSKNVTIENVTIEDCTGDNIWVTSKGMMNWPG-VYIPSESVTIRKCRTLRGRRNNIAAGASVGLLIDDCDIIEAGGDEIGPQLGIDLEGYADNSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGvHKKFGIDSIRKSTSETANRAVVTGNVIRGFQTGIAARGKTVTVSNNILEDISSIGIYPYLCDQAVVSSN-IIDSDCLHIWVRESKDIKVSDNKGTGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSTNVRIVDNDIDMIGPDYGIYFDKQSEVHLRDNLVKNAAFTAIRGYADQYSSYIKGNIIQDCKYMIAIHIDGGSKHMIKDNDITFRRGSNAGYGVYLIGANDSRLHNNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>A0A7U3TFK2 +---------YFIDFEQFGIKGDGTDATSTTNGFVAAFKRAVELGYSAVFVPEGTYLIDAVG-VGDYLPEYGGGLQFPSNIEVILHEKALFKVQSNDSTGYACFNLEGVENVTIRGGRIVGDRYEHNYRQdVNENRRTHEWGFGIQVRGSKNITIENVTIEDCTGDNIWVTSKGMMNWPG-EYIPSKSVTIRKCQTYRGRRNNIAAGASVGLLIDDCDIIEAGGDTIGPQLGIDLEGYADKSIKYQHPYEINVINCRFKDNGRGSMNINVSGKVNAIGNFCDDYIGYGFSTDVTISNNVITNETGvHKKFGIDSIRKSTSETANRAVIVGNVIRGFQTGIAARGKTVTVSDNILEDISSIGIYPYLCEQAVVSDN-IIDSDCLHIWVRESKDIKVSDNKGIGAANNVSIKVDASKDVLLSDNEVSG-KGGVRVSRSTNVRIVDNDIELIGADYGIYFDKQSEVHLRDNLIKNAAFTAIMGYADQYSSYIRGNIIQDCKYMIAVHIDGGAKHMIKDNDITFRRGSNAGYGIYLIGANDSRLHSNDIRVMDGFGLINSFYTIQSTNTKLIGNTYDTG-------------- +>A0A5J6TBR2 +---------YELECDRWGIFPDGTNPESTTRGFNDALTFAAAEGYKEIYIPKGVYKIDCVSRFGSK-PEYGGGIRNPSNLDVDMHTEATFLVLENDAVGYSLFYINLAENITMKGGRIIGDRYKHTYTYYEDKTKTHEWGYGVHIRGSKNINIENMFISDCTGDNIWVAANGMMNYEGSTYIPSKDVTVRKCTLMRGRRNGLATNGCEGLLVDDCTIEESGGaGGTRPEYGIDLEGFGEGGIKYDHPYKLIIRNCRIKNNGLGAISSFTAGKVIIEGNEVDDVISYGYSTDVTITNNQIINEGEIKPYGIDSLGVSSTETGNRASIKGNTIRGFNIGINAKGKGILVSKNTIEDVESIGIQVYQATSALVIGNRI-DADCTHIQMLYAEKTTVIGNESEGNTQNFAYKVTYSDRTVFSGNTLYDGDGGLDVGQSTLTKFKGNTLFLTGENFGVHWGSSSDLEVSGNTFHMGSGVAIFGYADLHTNIIKDNVIHDSKATYAIYLKGGSFHAVERNTVKIARNADFGYGIYIEGTTGVRMTGNDVAVTNGRDLTAPITTEKSAGTLVDGNKYN---------------- +>A0A2I6UI00 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALKDAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTdgVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGiDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAKNYYGIKVEDSSDV-VVNDNKQVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKTSQVKLVKsNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>A0A890URD5 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALKDAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTdgVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGiDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAKNYYGIKVEDSSDV-VVNDNKQVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKTSQVKLVKsNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>U5PXV9 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALKEAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFMVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTdgVPDNRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPAKGMMNWEGSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFSYGFSTDSTISNNTITNETGiDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVQVGNNKGKDAENYYGIKVEDSSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKTSQVKLIKsNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>S6BUP9 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALREAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTdgVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGvDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAENYYGIKVEDSSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKISQVKLVKsNWISCAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>A0A384XD57 +----NSNYMYFVDFEKFGIRSDGTEARATTEGWIAALKEAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTdgVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFSDDVFNYGFSTDSTISNNTITNETGiDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAENYYGIKVEASSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKISQVKLVKsNWISGAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>L0L8C8 +---------YFIDFEKHGIKSDGTAARETTDGFTYALNDAVNKGYKTVYVPKGDYLINGVG--EDRMPEYGGGIQFPSNIEVIFHKKAIFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMnVSKFRKTHEWGYGVHIRGSRNILVEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTERGRRNNIATDGCLGLLIDDCDIIEAGGDTIGPQLGIDLEGFAEDGIKYGHPYEINVVNNRIRNNGRGSLNINVSAKVHASNNFSDDVFSYGYSSDVSICNNKIINDSGKvRKYGIDSIRKSSTETGNRAIITGNHIIGFEIGICARGLGVKIANNYLKDISSIGIYPYLAEEVSVSDN-IVDSNCLHVWVRESKDVKISDNKTKGADNDFAYRVESSSDV-IISDSKSQANGGIQVIRSRKVTLKDNDLTLTGADYGIYWDKQSEVEVLHNTVRDAAMIAIAGNSNLYPSIVKGNNIKDCTYLVGLYMNGGRDHVIWDNDVSFKgvGSSNGGYGVQLIATTNAWLMDNKVRVSNGRTLSSAYESQSSYKTLYVNNAMQIG-------------- +>A0A1Z1DEW7 +----NSKYVYDIDFGKFGIKPDCTEAAATTEGFITALEDAVDQGYPKVYIPEGFYLIDAVGT-SGKLPEFGGGLRFPSNIEVIFHEKAVFIVDPNDATGYACFNLENVENVTLRGGVVIGDRYKHTYvqEGVPDNRKTHEWGYGLQIRGCRNIKVENMTLMDATGDNIWVPAKGMMNWEGSTYIPSEGITIDKCYTLRGRRNNLATNGCLGLNINDCDFVEAGGDTIGPAYGIDLEGFAENSIKYDHPYEINVTNCRFKRNGKGALTINVAGKAHATNNFSDDIISYGFSTDATISNNTITNESEElKEYGIDSIRKSSSETGNRAIITGNHIRGFKSGICARGVGVVASNNYLENISSVGIYAYLAKNVLMADNVI-NSDCLHVWVRESEDVKISNSKGKGAINNWGIKVEASSNVS-LNDNEHDSKGGVQVARSTDVRAWDNRFTLVGNEYGAYWDKTSEVrVFEGNHIFNPSTIAIAGYGDTYASSIVRNTIHDCKYLTAIYLSGGSQHFVKGNDIRFRRGANGGYGIKLTGTSGVKVIGNDVRTMDGCSLNASYDSSGSVNTQYANNTYHTG--RMLLHD------ +>A0A516KNA2 +----NSKYVYDIDFGKFGIKPDCTEAAATTEGFITALEDAVDQGYPKVYIPEGFYLIDAVGT-SGKLPEFGGGLRFPSNIEVIFHEKAVFIVDPNDATGYACFNLENVENVTLRGGVVIGDRYKHTYvqEGVPDNRKTHEWGYGLQIRGCRNIKVENMTLMDATGDNIWVPAKGMMNWEGSTYIPSEGITIDKCYTLRGRRNNLATNGCLGLNINDCDFVEAGGDTIGPAYGIDLEGFAENSIKYDHPYEINVTNCRFKRNGKGALTINVAGKAHATNNFSDDIISYGFSTDATISNNTITNESEElKEYGIDSIRKSSSETGNRAIITGNHIRGFKSGICARGVGVVASNNYLENISSVGIYAYLAKNVLMADNVI-NSDCLHVWVRESEDVKISNSKGKGAINNWGIKVEASSNVS-LNDNEHDSKGGVQVARSTDVRAWDNRFTLVGNEYGAYWDKTSEVrVFEGNHIFNPSTIAIAGYGDTYASSIVRNTIHDCKYLTAIYLSGGSQHFVKGNDIRFRRGANGGYGIKLTGTSGVKVIGNDVRTMDGCSLNASYDSSGSVNTQYANNTYHTG--RMLLHD------ +>A0A345MJP4 +----NSKYVYFVDFEKFGIKSDGTDAAATTSGWIAALKEAVDLGYPKVYVPAGLYLIDAVGKTDSL-PEYGGGLRFPSNIEVIFHEMALFKVEPNSSTGYACFNLENVENVTLRGGYVIGDRYEHDYTLdgVPNNRRTHEWGHCLHIRGCRNIYVENMTLMNATGDNIWVPAKGMMNWEGSTYIPSEGITIHKCTTIRGRRNNFATNGCIGLNIDDCDFIEAGGDVIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALNINVTGKVHATNNFTDDVISYGFSTDGTISNNTITNETGvHKPFGIDSIRKSSSETGNRTIITGNQIRGFASGICARGVGVIVSNNYLSDISSVGIYPYLSEEVLVSNN-IINSDCLHVWVRESKDVKVNNTKGKGAANNYGIKVEASHDV-VLNDNEHEAKGGIQIARSTNVRVKDNDLNLIGNGNGISWDKTSQVkILDGNWINGAVAIAISGYGEVYPTNIMRNTIEDCKYLIGIYLNGGSQHVIKDNDIMFRRGSNGGYGVQLKDTTDVRVYRNDVRTMDGGTLYSSFDSSGALSTKYVGNTMDAG-------------- +>A0A5B9NKS7 +---MNKELYYHIDLERFGIRDDLTEANATTQGFNAALKDAKEQGYHYFVFPEGKYLINTISNFGGL-PEYGGGIRIPSNIHIIMD-NPYFEAEANDRTGYSIFYLEAVENVEISGiGTICGDRYNHDYvrDLKDDRTKTHEWGFGIHIRGCRRVAIKGLTVKNCTGDNIWIPAKGMMNFPG-DYTPSRDILIQDCDLIHGRRNNLATNGCYGLTVERCDIKEAGGDTIGPQLGIDLEGYGDKGIKYDHPYEITIKNNWIKNNGRGALTAHTSGKVLIEGNFTDAVISYAYSTDVKIKDNFIINEtGQEKPYGIDSIGVSSSETANRVNISGNTVSGFKTGICARGSKVKVRNNEVEGATAAAIQIFQCEKAEVSDN-TTDGNAVGLLIQQSKTVEASDNTFRGAENKYGIKIgQDSSDIILKDNRIRG-FGGIFCESVQNVVVRDHDINLTGSGYGVYFDAKSCVFLDGVTIYNPENTSVYGLADEYAAIIKGVEVIGCKSIIGIYLHGGINHDIKGNTVRFKRGKDQGYGIYLDGTKGAVLARNDVVSTDGFKLSAAYKTDESEQTTLIEN------------------- +>A0A386K842 +---MSKGLYYHIDLERFGIKDDLTEANATTQGFNAALKDAKDQGYHYFVFPEGKYLINAVSNFGGL-PEYGGGIRIPSNINIIMD-NPYFEAEANDQTGYSIFYLEAVENVKISGiGTICGDRYNHDYvrDLKDDRTKTHEWGFGIHIRGCRRVEIKGLTVKNCTGDNIWIPAKGMMNWP-TDYTPSRDILIQDCDLIQGRRNNLATNGCYGLTVERCDIKEAGGDTIGPQLGIDLEGYGDKGIKYDHPYEITIKNNWIKNNGRGALTAHTSGKVLIEGNFTDAVISYAYSTDVKIKDNFIINEtGQEKPYGIDSIGVSSSETANRVNISGNTVSGFKTGICARGSKVKIHGNEVEGATAAAIQIYQCEKVEVSDN-TTDGNAVGLLIQQSKTVEASDNTFRGSENKYGIKIgQDSSDIILKDNRIRG-FGGIFCESAQKVIVRDHDIDLTGSGYGVYFDAKSSVFLDGVTIYNPENTPVYGLADEFAAIMKDVEVIGCKSIIGIYMHGGFGHDIKGNTVRFRRGKDQGYGIFLDGTKSAVLTRNDVLSTDGFKLSAAYKTDGSERTTLIEN------------------- +>D0VXF4 +----NSNYMYFVDFEKFGIRSDGTEARATTDGWIAALREAVELGYHTVYVPEGLYLIDAVSTVGSL-PEYGGGLMFPSNIEVIFHERALFQVAPNSSTGYACFNLENVENVTLRGGTIIGDRYEHDYVTdgVPDKRKTHEWGHGIHIRGCRNITVENATVMNCTGDNIWVPSKGMMNWEDSTYIPSEGITIRKCILIRGRRNNLATNGCLGMNVDDCDFIEAGGDTIGPAFGIDLEGFAENSIKYDHPYEINITNCRFKRNGKGALTSTLQGKFMLLIT-SPMMAQLWFSTDSTISNNTITNETGvDKPYGIDSIRKSSSETGNRTIITGNQIRGFATGICARGVGVIVSQNYLEDISSVGINPYLSEDVMVANNTI-NSDCLHVWVRNSVDVKVGNNKGKGAENYYGIKVEDSSDV-VVNDNKHVAKGGIQVARSTNVRIKDNDLTLIGNGNGISWDKISQVKLVKsNWISCAVAAAISGYADAYSTIISYNILEDCKYLIAIYLNGGAHHMLKGNDIMFRRGANGGYGVQLVNTTQARLISNDVRTMDGCTLHASYDSTGSTYTKYAYNTY----------------- +>A0A0A0PLR7 +-------------------------------------------------------------------PEYGGGIQFPSNIEVIFHKEAVFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMnVSKFRKTHEWGYGVHIRGCRNILVEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTERGRRNNIATDGCLGLLIDDCDIVEAGGDTIGPQLGIDLEGFAEDGIKYGHPYEINITNNRFRENGRGSLNINVSAKVHATNNFSDDVFSYGYSSDVSICNNKIINESGKvRKYGIDSIRKSSTETGNRAIITGNHIIGFEIGICARGLGVKIANNYLKDISSIGIYPYLAEEVSVSDN-IIDSNCLHVWVRESKDVKISDNKTKGAANHFAYRVEASSDV-LISDSKSQSKGGIQVIRSRKVILKDNDLSLTGADYGIQWDKQSEVEVLNNTVRDAAMIAIAGNSELYPSVIKGNNIKDCTYLVGLYVNGGSNHILWDNDISFrgTGTTNGGYGVQLVGTENVWLMNNKVRTSNGRLLSSAYESRNSKKTMYINNALQAG-------------- +>A0A0A0PUI4 +-------------------------------------------------------------------PEYGGGIQFPSNIEVIFHKEAVFKVEPNSSTGYACFNLENVDNVILRGGCVVGERFEHDYDMnVSKFRKTHEWGYGVHIRGCRNILVEDMHISDCTGDCIWVPAHGMMNWGDTVYIPSESITIRKCRTERGRRNNIATDGCLGLLIDDCDIVEAGGDTIGPQLGIDLEGFAEDGIKYGHPYEINITNNRFRENGRGSLNINVSAKVHATNNFSDDVFSYGYSSDVSICNNKIINESGKvRKYGIDSIRKSSTETGNRAIITGNHIIGFEIGICARGLGVKIANNYLKDISSIGIYPYLAEEVSVSDN-IIDSNCLHVWVRESKDVKISDNKTKGAANHFAYRVEASSDV-LISDSKSQSKGGIQVIRSRKVILKDNDLSLTGADYGIQWDKQSEVEVLNNTVRDAAMIAIAGNSELYPSVIKGNNIKDCTYLVGLYVNGGSNHILWDNDISFrgTGTTNGGYGVQLVGTENVWLMNNKVRTSNGRLLSSAYESRNSKKTMYINNALQAG-------------- +>A0A5P8PIG3 +---------YPVNLEEWGINKDFQEPEATTEAFNKAFTYAKNMGYFEVWVPPGNYLIDGVNESNIYATENGGGIHLHSNTHYKLNPESVFKINANNAQGYSVFYIGLAYNVTLEGGQLIGDRHEHDYSTVTQNRNTHEFGFGVNVHGSERVNIVNVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDVIGPQLGIDFEGYAENGIKYAHPYNLQLKNSRFRDNGRGCFTAHAVGKAIISENFFDDRVSYGFGTDISIVDNHIINDGEVRDLAIDSIQPPSYDNANRVKISGNKIKGFKKGMTIRGKEIDVTDNDLNNITETGIHVYLAEEITVNENRV-NSDCVPLNIQISKKVNVSDNTFKGGAEKYGVIVSgEVEDISFKDNHI-EAGGGIDAGSAKNVRIlSKNEIFVKGKLNALRNNAGSTVKVNGLNIYDPAAYPMeldgsAGALDIKNV-----SIYGCKAFIAINIKNGRRHKIKNNDIVFERETNGGYGVYLSGTERTKLMDNDVSTSNDFAIGAPFHTEGSMYSTIMHNYYDSG-------------- +>M4ZRV1 +---------YPLNLEEWGINKEFQEPEETTAAFNKAFEYAKSMGYFKILVPPGNFLIDGVNESNIYATENGGGIHLHSNTHYLLHPESVFKINANDAQGYSVFYIGLAYNVTLEGGQLIGDRHEHDYSTSTQNRNTHEFGFGVNVHGSERVNIINVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDTIGPQLGIDFEGYAENGVKYAHPYNLQVKDSRFKNNGRGCFTAHAVGKAIISKNFFDDRVSYGFGTDISIVDNHIINDGEVRPLAIDSIQPPSYDNANRVKISGNTIKGFKKGMTIRGKEVDVIDNKLNNITDTGIHVYLAEEITVNENRV-NSDCVPLNIQISEKVNVSDNTFKGGSEKYGVVISgEVEDISFKDNHI-EAGGGIDAGVAKNVRIlSKNEIFVKGKLNALRNNAGSTVKVNGLNIYDPAayPMELDGSAGALDIR--NVSIYGCKAFIAINIKNGKSHKIKNNDIIFNRGSNGGYGIHLSGTEKAKLTNNYVSTSDGFAIGSPYHTENSTYSTVMNNYYDSG-------------- +>A0A5P8PHR1 +---------YPVNLEEWGINKDFQEPEATTEAFNRAFTYAKNMGYFEVWVPPGNYLIDGVNESNVYATENGGGIHLHSNTHYKLNPESVFKINANDAQGYSVFYVGLAYNVTLEGGQLIGDRYEHNYSTVAPNRSTHEFGFGVNVHGSERVNIINVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDIIGPQLGIDFEGYAENGIKYAHPYNLQLKNSRFKDNGRGCFTAHATGKAIISENFFDDRVSYGFGTDISIVDNHIINDGEVRPLAIDSIQPPSYDNANRVKVAGNKIKGFKKGMTIRGKEVDVTDNDLNDVTETGIHVYLAEEITVNENRV-NSDCVPLNIQISKKVNVSDNTFKGGAEKYGVVISgEVEDISFKDNHI-EAGGGIDAGSAKNVRIlSKNEIFVKGKLNALRNNPGSTMKVNGLNIYDPAAYPMELDGSAGSLDIKNVSIYGCKAFIAINIKNGRRHKIKNNDIIFERETNGGYGIYLSGTERTKLMDNDVSTSNDFAIGSPFHTENAMYSTIMHNYYDSG-------------- +>A0A5P8PI75 +---------YSVNLEEWGINKDFQEPEATTEAFNKAFTYAKNMGYFEVWVPPGNYLIDGVNESNIYATENGGGIHLHSNTHYKLNPESVFKINANNAQGYSVFYIGLAYNVTLEGGQLIGDRHEHDYSTVTQNRNTHEFGFGVNVHGSERVNIVNVRSRDMTGDNILITNKGNMNYPGQTYIPSKNVTVENCYLETARRNNLSAVGCDGVLIDNCDFIAAGGDVIGPQLGIDFEGYAENGIKYAHPYNLQLKNSRFRDNGRGCFTAHAVGKAIISENFFDDRVSYGFGTDISIVDNHIINDGEIRALAIDSIQPPSYDNANRVKISGNKIKGFKKGMTIRGKEIDVTDNDLNNITETGIHVYLAEEITVNENRV-NSDCVPLNIQISKKVNVSDNTFKGGAEKYGVIVSgEVEDISFKDNHI-EAGGGIDAGSAKNVRIlSKNEIFVKGKLNALRNNPGSTVKVNGLNIYDPAAYPMeldgsAGALDIKNV-----SIYGCKAFIAMNIKNGRRHKIKNNDIVFERETNGGYGVYLSGTERTKLTDNDVSTSNDFAIGAPFHTEGSMYSTIMYNYYDSG-------------- diff --git a/test/unit/test_af2_feature_finalizer.py b/test/unit/test_af2_feature_finalizer.py new file mode 100644 index 00000000..c45dd02c --- /dev/null +++ b/test/unit/test_af2_feature_finalizer.py @@ -0,0 +1,486 @@ +"""AlphaFold 2 features from a local MMseqs2 bundle, through AlphaFold 2's own code. + +Every property asserted here is one that fails silently when wrong: a feature key +another source lacks crashes multimer pairing only when that chain happens to come +first; a template profile built from the merged alignment returns different hits +without complaint; a species lost from a header simply pairs nothing. +""" + +from __future__ import annotations + +import json +from pathlib import Path +import pickle + +import numpy as np +import pytest + +pipeline = pytest.importorskip( + "alphafold.data.pipeline", reason="needs the AlphaFold 2 data pipeline" +) +from alphafold.common import residue_constants # noqa: E402 + +from alphapulldown.af2_feature_finalizer import ( # noqa: E402 + Af2FeatureFinalizationSettings, + Af2FeatureFinalizer, +) +from alphapulldown.feature_batch import PROTEIN, RNA, FeatureRequest # noqa: E402 + + +FIXTURES = Path(__file__).resolve().parents[1] / "test_data" / "features" / "af2_features" + +# Measured on a natively generated (jackhmmer) pickle from the shared feature +# store. Local features must carry every one of these, or a multimer mixing the +# two sources fails on the missing key. +NATIVE_KEYS = { + "aatype", "between_segment_residues", "deletion_matrix_int", + "deletion_matrix_int_all_seq", "domain_name", "msa", "msa_all_seq", + "msa_species_identifiers", "msa_species_identifiers_all_seq", "num_alignments", + "residue_index", "seq_length", "sequence", "template_aatype", + "template_all_atom_masks", "template_all_atom_positions", + "template_confidence_scores", "template_domain_names", "template_release_date", + "template_sequence", "template_sum_probs", +} +ACCESSION_KEYS = { + "msa_uniprot_accession_identifiers", + "msa_uniprot_accession_identifiers_all_seq", +} + +QUERY = "MKTAYIAKQRQISFVKSHFSRQ" + + +class RecordingSearcher: + """Stands in for hmmsearch and remembers the profile it was handed.""" + + input_format = "sto" + output_format = "sto" + + def __init__(self): + self.queries: list[str] = [] + + def query(self, text): + self.queries.append(text) + return "RAW_HITS" + + def get_template_hits(self, output_string, input_sequence): + return [] + + +class NoHitFeaturizer: + """What AlphaFold 2's HmmsearchHitFeaturizer returns when nothing is found.""" + + def get_templates(self, query_sequence, hits): + num_res = len(query_sequence) + + class Result: + features = { + "template_aatype": np.zeros( + (1, num_res, len(residue_constants.restypes_with_x_and_gap)), + np.float32, + ), + "template_all_atom_masks": np.zeros( + (1, num_res, residue_constants.atom_type_num), np.float32 + ), + "template_all_atom_positions": np.zeros( + (1, num_res, residue_constants.atom_type_num, 3), np.float32 + ), + "template_domain_names": np.array([b""], dtype=object), + "template_sequence": np.array([b""], dtype=object), + "template_sum_probs": np.array([0], dtype=np.float32), + } + + return Result() + + +def _a3m(records): + return "".join(f">{description}\n{sequence}\n" for description, sequence in records) + + +def _write_bundle(msa_dir: Path, name: str, sequence: str, *, uniref90, mgnify, + small_bfd, paired) -> None: + msa_dir.mkdir(parents=True, exist_ok=True) + unpaired = [("query", sequence), *uniref90, *mgnify, *small_bfd] + paired_records = [("query", sequence), *paired] + (msa_dir / f"{name}_mmseqs_msa.json").write_text( + json.dumps( + { + "schemaVersion": 3, + "name": name, + "sequence": sequence, + "unpairedMsa": _a3m(unpaired), + "pairedMsa": _a3m(paired_records), + "unpairedDepth": len(unpaired), + "pairedDepth": len(paired_records), + "unpairedDatabaseRows": [ + {"name": "uniref90", "rows": len(uniref90)}, + {"name": "mgnify", "rows": len(mgnify)}, + {"name": "small_bfd", "rows": len(small_bfd)}, + ], + "provenance": {"schema_version": 5, "fixture": name}, + } + ), + encoding="utf-8", + ) + + +def _mutate(sequence: str, position: int, residue: str) -> str: + return sequence[:position] + residue + sequence[position + 1 :] + + +def _insert(sequence: str, position: int, insertion: str) -> str: + return sequence[:position] + insertion + sequence[position:] + + +def _standard_bundle(msa_dir: Path, name: str = "alpha", sequence: str = QUERY): + """Rows named by database, one uniref90 hit with an insertion, UniProt species.""" + _write_bundle( + msa_dir, + name, + sequence, + uniref90=[ + ("UniRef90_U1 uniref hit", _mutate(sequence, 3, "W")), + # A three-residue insertion before position 5 -- lowercase, as stitched. + # It also carries its own substitution: a row whose match columns equal + # the query's is a duplicate of it, and AlphaFold 2 drops it as one. + ("UniRef90_U2 inserted", _insert(_mutate(sequence, 11, "W"), 5, "ggg")), + ], + mgnify=[("MGYP000000001", _mutate(sequence, 7, "W"))], + small_bfd=[("BFD_B1", _mutate(sequence, 9, "W"))], + paired=[ + ("sp|P12345|KIN1_HUMAN kinase OS=Homo sapiens OX=9606", _mutate(sequence, 2, "V")), + ("tr|Q67890|Q67890_MOUSE kinase OS=Mus musculus OX=10090", _mutate(sequence, 4, "V")), + ], + ) + + +def _finalizer(tmp_path: Path, **overrides): + settings = dict( + output_dir=tmp_path / "features", + msa_input_dir=tmp_path / "msas", + max_template_date="2050-01-01", + template_seqres_database_id="pdb-seqres-2050", + template_mmcif_database_id="mmcif-2050", + ) + settings.update(overrides) + searcher = RecordingSearcher() + finalizer = Af2FeatureFinalizer( + settings=Af2FeatureFinalizationSettings(**settings), + template_searcher=searcher, + template_featurizer=NoHitFeaturizer(), + ) + return finalizer, searcher + + +def _features(tmp_path: Path, name: str = "alpha") -> dict: + with open(tmp_path / "features" / f"{name}.pkl", "rb") as handle: + return pickle.load(handle).feature_dict + + +def _generate(tmp_path, name="alpha", sequence=QUERY, **overrides): + finalizer, searcher = _finalizer(tmp_path, **overrides) + result = finalizer.generate([FeatureRequest(name=name, sequence=sequence)]) + assert result.failures == (), result.failures + return result, searcher + + +def test_features_carry_the_native_key_set_plus_accession_identifiers(tmp_path): + _standard_bundle(tmp_path / "msas") + _generate(tmp_path) + assert set(_features(tmp_path)) == NATIVE_KEYS | ACCESSION_KEYS + + +def test_insertions_reach_the_deletion_matrix(tmp_path): + """The point of recovering insertions: native features have them, and until + now every local MMseqs2 alignment produced an all-zero deletion matrix.""" + _standard_bundle(tmp_path / "msas") + _generate(tmp_path) + features = _features(tmp_path) + + deletions = features["deletion_matrix_int"] + assert deletions.shape == features["msa"].shape + assert deletions.sum() == 3, "three inserted residues, counted once" + # Recorded against the residue that follows the insertion. + row = int(np.nonzero(deletions.sum(axis=1))[0][0]) + assert deletions[row, 5] == 3 + + +def test_rows_follow_alphafold2s_merge_order(tmp_path): + _standard_bundle(tmp_path / "msas") + _generate(tmp_path) + msa = _features(tmp_path)["msa"] + mutated_at = [int(np.nonzero(row != msa[0])[0][0]) if (row != msa[0]).any() else None + for row in msa] + # query, uniref90 (3, 11), then BFD (9) before MGnify (7), as AlphaFold 2 merges. + assert mutated_at == [None, 3, 11, 9, 7] + + +def test_templates_are_searched_from_uniref90_alone(tmp_path): + _standard_bundle(tmp_path / "msas") + _, searcher = _generate(tmp_path) + [profile] = searcher.queries + assert "UniRef90_U1" in profile + assert "MGYP000000001" not in profile and "BFD_B1" not in profile + + +def test_pairing_features_come_from_uniprot_with_parsed_species(tmp_path): + _standard_bundle(tmp_path / "msas") + _generate(tmp_path) + features = _features(tmp_path) + + assert list(features["msa_species_identifiers_all_seq"]) == [b"", b"HUMAN", b"MOUSE"] + assert list(features["msa_uniprot_accession_identifiers_all_seq"]) == [ + b"", b"P12345", b"Q67890", + ] + # Not a copy of the unpaired features, which is what the remote path uses. + assert features["msa_all_seq"].shape[0] == 3 + assert features["msa"].shape[0] == 5 + + +def test_no_network_is_ever_touched(tmp_path, monkeypatch): + """A batch of thousands of chains must not start calling UniProt REST.""" + import urllib.request + + def refuse(*args, **kwargs): + raise AssertionError("the local AlphaFold 2 path queried the network") + + monkeypatch.setattr(urllib.request, "urlopen", refuse) + _write_bundle( + tmp_path / "msas", + "alpha", + QUERY, + uniref90=[("UniRef90_A0A0A0A0A0 no species in this header", _mutate(QUERY, 3, "W"))], + mgnify=[], + small_bfd=[], + # A bare accession: exactly the case the shared helper would look up. + paired=[("P12345", _mutate(QUERY, 2, "V"))], + ) + _generate(tmp_path) + + +def test_published_pickle_is_a_monomeric_object_and_is_reused(tmp_path): + from alphapulldown.objects import MonomericObject + + _standard_bundle(tmp_path / "msas") + first, searcher = _generate(tmp_path) + assert [artifact.name for artifact in first.written] == ["alpha"] + with open(tmp_path / "features" / "alpha.pkl", "rb") as handle: + monomer = pickle.load(handle) + assert isinstance(monomer, MonomericObject) + assert monomer.sequence == QUERY and monomer.skip_msa is False + assert list((tmp_path / "features").glob("alpha_feature_metadata_*.json")) + + again, searcher_again = _generate(tmp_path) + assert [artifact.name for artifact in again.reused] == ["alpha"] + assert searcher_again.queries == [], "a reused artifact must not search again" + + +def test_changed_template_settings_are_not_served_from_cache(tmp_path): + _standard_bundle(tmp_path / "msas") + _generate(tmp_path) + moved, _ = _generate(tmp_path, max_template_date="2020-01-01") + assert [artifact.name for artifact in moved.written] == ["alpha"] + + +def test_hhsearch_cache_tracks_pdb70_without_rebuilding_the_msa(tmp_path): + _standard_bundle(tmp_path / "msas") + bundle = tmp_path / "msas" / "alpha_mmseqs_msa.json" + original_bundle = bundle.read_bytes() + options = dict(template_searcher="hhsearch", template_pdb70_database_id="pdb70-v1") + first, _ = _generate(tmp_path, **options) + assert [artifact.name for artifact in first.written] == ["alpha"] + again, searcher = _generate(tmp_path, **options) + assert [artifact.name for artifact in again.reused] == ["alpha"] + assert searcher.queries == [] + + changed, searcher = _generate( + tmp_path, **{**options, "template_pdb70_database_id": "pdb70-v2"} + ) + assert [artifact.name for artifact in changed.written] == ["alpha"] + assert len(searcher.queries) == 1 + assert bundle.read_bytes() == original_bundle + with open(tmp_path / "features" / "alpha.pkl", "rb") as handle: + provenance = pickle.load(handle).local_msa_provenance["af2_templates"] + assert provenance["pdb70_database_id"] == "pdb70-v2" + assert "pdb_seqres_database_id" not in provenance + + +@pytest.mark.parametrize("searcher,unused_id", [ + ("hmmsearch", "template_pdb70_database_id"), + ("hhsearch", "template_seqres_database_id"), +]) +def test_unused_template_database_does_not_invalidate_features(tmp_path, searcher, unused_id): + _standard_bundle(tmp_path / "msas") + options = dict(template_searcher=searcher, template_pdb70_database_id="pdb70-v1") + _generate(tmp_path, **options) + options[unused_id] = "unused-database-v2" + result, recording = _generate(tmp_path, **options) + assert [artifact.name for artifact in result.reused] == ["alpha"] + assert recording.queries == [] + + +@pytest.mark.parametrize("missing", [None, "", " "]) +def test_hhsearch_requires_a_pdb70_identity(tmp_path, missing): + finalizer, _ = _finalizer( + tmp_path, template_searcher="hhsearch", template_pdb70_database_id=missing + ) + with pytest.raises(ValueError, match="template_pdb70_database_id"): + finalizer.generate([]) + + +def test_hhsearch_does_not_require_an_unused_seqres_identity(tmp_path): + _standard_bundle(tmp_path / "msas") + result, _ = _generate( + tmp_path, template_searcher="hhsearch", template_seqres_database_id=None, + template_pdb70_database_id="pdb70-v1", + ) + assert [artifact.name for artifact in result.written] == ["alpha"] + + +def test_compressed_output_round_trips(tmp_path): + import lzma + + _standard_bundle(tmp_path / "msas") + _generate(tmp_path, compress=True) + with lzma.open(tmp_path / "features" / "alpha.pkl.xz", "rb") as handle: + assert pickle.load(handle).sequence == QUERY + + +def test_rna_is_refused_by_name(tmp_path): + finalizer, _ = _finalizer(tmp_path) + result = finalizer.generate( + [FeatureRequest(name="trna", sequence="ACGU", molecule_type=RNA)] + ) + assert [failure.name for failure in result.failures] == ["trna"] + assert "protein" in result.failures[0].error + + +def _local_monomer(tmp_path: Path, name: str, sequence: str): + _standard_bundle(tmp_path / "msas", name, sequence) + _generate(tmp_path, name=name, sequence=sequence) + with open(tmp_path / "features" / f"{name}.pkl", "rb") as handle: + return pickle.load(handle) + + +def _native_like_monomer(): + """An older pickle with 21 keys and no accession identifiers at all.""" + with open(FIXTURES / "protein" / "P61626.pkl", "rb") as handle: + return pickle.load(handle) + + +@pytest.mark.parametrize("local_first", (True, False)) +def test_local_chain_pairs_with_a_pickle_from_another_source(tmp_path, local_first): + """AlphaFold 2 pairing takes its key set from the FIRST chain and indexes every + other chain with it, so an extra key crashes only in one order (issue #619). + Both orders, through the real pairing code.""" + from alphapulldown.objects import MultimericObject + + local = _local_monomer(tmp_path, "alpha", QUERY) + native = _native_like_monomer() + chains = [local, native] if local_first else [native, local] + + merged = MultimericObject(interactors=chains, pair_msa=True).feature_dict + + total = len(local.sequence) + len(native.sequence) + assert merged["aatype"].shape == (total,) + assert merged["msa"].shape[1] == total + + +def test_two_local_chains_pair_the_species_they_share(tmp_path): + """Which rows pair, not merely that pairing ran: HUMAN and MOUSE occur in both + chains' UniProt alignments, so those rows line up in the paired block.""" + from alphapulldown.objects import MultimericObject + + first = _local_monomer(tmp_path, "alpha", QUERY) + second_sequence = _mutate(QUERY, 12, "L") + second = _local_monomer(tmp_path, "beta", second_sequence) + + merged = MultimericObject(interactors=[first, second], pair_msa=True).feature_dict + + # The merged multimer MSA is in the model's residue order, not HHblits'. + to_id = residue_constants.restype_order_with_x + human_row = [to_id[r] for r in _mutate(QUERY, 2, "V") + _mutate(second_sequence, 2, "V")] + mouse_row = [to_id[r] for r in _mutate(QUERY, 4, "V") + _mutate(second_sequence, 4, "V")] + # An unpaired row carries one chain's residues and gaps across the other, so + # both chains' hits can only sit on one row if pairing put them there. + rows = [list(row) for row in merged["msa"]] + assert human_row in rows, "the HUMAN hits of both chains must share one row" + assert mouse_row in rows, "the MOUSE hits of both chains must share one row" + # And a hit present in only one chain's alignment is never paired. + unpaired_hit_a = [to_id[r] for r in _mutate(QUERY, 3, "W") + second_sequence] + assert unpaired_hit_a not in rows + + +def test_a_homomer_of_a_local_chain_assembles(tmp_path): + """Two copies of one chain: AF2 merges identical entities into a dense MSA + instead of pairing them, a different code path from the heteromer.""" + from alphapulldown.objects import MultimericObject + + first = _local_monomer(tmp_path, "alpha", QUERY) + with open(tmp_path / "features" / "alpha.pkl", "rb") as handle: + second = pickle.load(handle) + + merged = MultimericObject(interactors=[first, second], pair_msa=True).feature_dict + + assert merged["aatype"].shape == (2 * len(QUERY),) + assert merged["msa"].shape[1] == 2 * len(QUERY) + + +def test_local_chains_assemble_without_pairing(tmp_path): + """pair_msa=False skips species pairing and block-diagonalises the MSAs.""" + from alphapulldown.objects import MultimericObject + + first = _local_monomer(tmp_path, "alpha", QUERY) + second = _local_monomer(tmp_path, "beta", _mutate(QUERY, 12, "L")) + + merged = MultimericObject(interactors=[first, second], pair_msa=False).feature_dict + + to_id = residue_constants.restype_order_with_x + # Unpaired, a HUMAN hit shares a row with no other chain's residues. + human_row = [to_id[r] for r in _mutate(QUERY, 2, "V") + _mutate(QUERY, 2, "V")] + assert human_row not in [list(row) for row in merged["msa"]] + assert merged["msa"].shape[1] == 2 * len(QUERY) + + +def test_a_chopped_local_chain_pairs_with_a_full_one(tmp_path): + """Issue #619's shape: a full chain first, a chopped chain second. The chopped + chain must keep the accession identifiers, row-aligned, or pairing crashes.""" + from alphapulldown.objects import ChoppedObject, MultimericObject + + full = _local_monomer(tmp_path, "alpha", QUERY) + source = _local_monomer(tmp_path, "beta", _mutate(QUERY, 12, "L")) + region = (3, 15) + chopped = ChoppedObject( + source.description, source.sequence, source.feature_dict, [region] + ) + chopped.prepare_final_sliced_feature_dict() + assert ( + chopped.feature_dict["msa_uniprot_accession_identifiers_all_seq"].shape[0] + == chopped.feature_dict["msa_all_seq"].shape[0] + ) + + merged = MultimericObject(interactors=[full, chopped], pair_msa=True).feature_dict + + region_length = region[1] - region[0] + 1 + assert merged["aatype"].shape == (len(QUERY) + region_length,) + + +@pytest.mark.parametrize("damage", ("spans_do_not_add_up", "no_spans")) +def test_a_bundle_unusable_to_alphafold2_is_deleted_so_it_is_rebuilt(tmp_path, damage): + """Rejecting such a bundle and leaving it in place fails the same finalization on + every retry: its Shard completion still validates, so no repair is scheduled. + Deleting it is what gets it rebuilt.""" + _standard_bundle(tmp_path / "msas") + bundle_path = tmp_path / "msas" / "alpha_mmseqs_msa.json" + bundle = json.loads(bundle_path.read_text()) + if damage == "no_spans": + del bundle["unpairedDatabaseRows"] + else: + bundle["unpairedDatabaseRows"][0]["rows"] += 1 + bundle_path.write_text(json.dumps(bundle)) + + finalizer, _ = _finalizer(tmp_path) + result = finalizer.generate([FeatureRequest(name="alpha", sequence=QUERY)]) + + assert [failure.name for failure in result.failures] == ["alpha"] + assert "row spans" in result.failures[0].error + assert not bundle_path.exists() diff --git a/test/unit/test_af2_msa_inputs.py b/test/unit/test_af2_msa_inputs.py new file mode 100644 index 00000000..0e4d9454 --- /dev/null +++ b/test/unit/test_af2_msa_inputs.py @@ -0,0 +1,100 @@ +"""Cutting an MSA bundle into the alignments AlphaFold 2 builds features from. + +No AlphaFold import: this is string slicing, and it has to be right in every +environment -- a wrong cut does not fail, it hands AlphaFold 2 another database's +rows or a template profile built from the wrong alignment. +""" + +from __future__ import annotations + +import pytest + +from alphapulldown import af2_feature_finalizer +from alphapulldown.af2_feature_finalizer import af2_msa_inputs +from alphapulldown.feature_batch import SearchedMsas + + +QUERY = "MKTAYI" + + +def _msas(uniref90=2, mgnify=2, small_bfd=2, paired=3) -> SearchedMsas: + """Distinguishable rows: U/M/B for each database, P for UniProt.""" + + def rows(prefix, count): + return [(f"{prefix}{index}", f"{prefix}KTAYI") for index in range(count)] + + unpaired = [("query", QUERY), *rows("U", uniref90), *rows("M", mgnify)] + unpaired += rows("B", small_bfd) + return SearchedMsas( + unpaired="".join(f">{d}\n{s}\n" for d, s in unpaired), + paired="".join( + f">{d}\n{s}\n" for d, s in [("query", QUERY), *rows("P", paired)] + ), + unpaired_rows=( + ("uniref90", uniref90), + ("mgnify", mgnify), + ("small_bfd", small_bfd), + ), + ) + + +def _names(a3m: str) -> list[str]: + return [line[1:] for line in a3m.splitlines() if line.startswith(">")] + + +def test_main_alignment_follows_alphafold2_merge_order(): + # The bundle merges uniref90, mgnify, small_bfd; AlphaFold 2 merges uniref90, + # BFD, MGnify (pipeline.py:265). Order decides what its MSA sampling sees first. + inputs = af2_msa_inputs(_msas()) + assert _names(inputs.main_a3m) == ["query", "U0", "U1", "B0", "B1", "M0", "M1"] + + +def test_templates_come_from_uniref90_alone(): + inputs = af2_msa_inputs(_msas()) + assert _names(inputs.template_a3m) == ["query", "U0", "U1"] + + +def test_caps_count_the_query_row_as_alphafold2_does(monkeypatch): + # jackhmmer's max_sto_sequences stops at that many sequence NAMES, query first, + # so a cap of 3 means the query plus two hits. + monkeypatch.setattr( + af2_feature_finalizer, "AF2_MAX_SEQUENCES", {"uniref90": 3, "mgnify": 2} + ) + inputs = af2_msa_inputs(_msas(uniref90=5, mgnify=5, small_bfd=5)) + + assert _names(inputs.template_a3m) == ["query", "U0", "U1"] + assert _names(inputs.main_a3m) == [ + "query", "U0", "U1", "B0", "B1", "B2", "B3", "B4", "M0", + ] + + +def test_paired_alignment_is_uniprot_truncated_like_all_seq_msa_features(monkeypatch): + monkeypatch.setattr(af2_feature_finalizer, "PAIRED_MAX_SEQUENCES", 3) + inputs = af2_msa_inputs(_msas(paired=10)) + assert _names(inputs.paired_a3m) == ["query", "P0", "P1"] + + +def test_real_defaults_are_alphafold2s(): + assert af2_feature_finalizer.AF2_MAX_SEQUENCES == { + "uniref90": 10_000, + "mgnify": 501, + } + assert af2_feature_finalizer.PAIRED_MAX_SEQUENCES == 50_000 + + +def test_a_bundle_without_row_spans_is_refused(): + """Without spans there is no uniref90 to build templates from -- and no way to + fake one, since the merged alignment has lost the boundaries.""" + msas = _msas() + spanless = SearchedMsas(unpaired=msas.unpaired, paired=msas.paired) + with pytest.raises(ValueError): + af2_msa_inputs(spanless) + + +def test_a_bundle_with_no_paired_alignment_is_refused(): + msas = _msas() + unpaired_only = SearchedMsas( + unpaired=msas.unpaired, paired="", unpaired_rows=msas.unpaired_rows + ) + with pytest.raises(ValueError, match="paired"): + af2_msa_inputs(unpaired_only) diff --git a/test/unit/test_af2_template_stack.py b/test/unit/test_af2_template_stack.py new file mode 100644 index 00000000..ca241fff --- /dev/null +++ b/test/unit/test_af2_template_stack.py @@ -0,0 +1,170 @@ +"""Exercise template construction and finalization through their caller interfaces.""" +from unittest.mock import Mock, patch + +import pytest + +from alphapulldown.af2_feature_finalizer import build_af2_template_stack +from alphapulldown.scripts import create_individual_features as legacy +from alphapulldown.scripts import finalize_batch_features as cli +from alphapulldown.scripts._mmseqs2_cli import ( + require_template_flags, + required_template_flag_names, +) +from absl.testing import flagsaver +from types import SimpleNamespace + + +@pytest.fixture +def finalization_flags(tmp_flags, tmp_path): + with flagsaver.flagsaver(): + tmp_flags.msa_input_dir = str(tmp_path / "msas") + tmp_flags.template_seqres_database_id = "seqres-v1" + tmp_flags.template_pdb70_database_id = "pdb70-v1" + tmp_flags.template_mmcif_database_id = "mmcif-v1" + tmp_flags.keep_msas = False + (tmp_path / "a.fasta").write_text(">query\nACDE\n") + yield tmp_flags + + +@pytest.mark.parametrize("hhsearch", [False, True]) +def test_template_stack_resolves_defaults_without_mutating_flags(finalization_flags, hhsearch): + finalization_flags.use_hhsearch = hhsearch + before = finalization_flags.flag_values_dict() + settings = legacy.af2_template_stack_settings() + assert settings.searcher_name == ("hhsearch" if hhsearch else "hmmsearch") + assert settings.pdb70_database_path == "/db/pdb70/pdb70" + assert settings.pdb_seqres_database_path == "/db/pdb_seqres/pdb_seqres.txt" + assert settings.template_mmcif_dir == "/db/pdb_mmcif/mmcif_files" + assert finalization_flags.flag_values_dict() == before + + +def test_template_stack_honors_overrides_without_a_data_root(finalization_flags): + finalization_flags.data_dir = None + finalization_flags.pdb70_database_path = "/custom/pdb70" + settings = legacy.af2_template_stack_settings() + assert settings.pdb70_database_path == "/custom/pdb70" + assert settings.pdb_seqres_database_path is None + + +@pytest.mark.parametrize("hhsearch", [False, True]) +def test_template_factory_builds_the_selected_search_and_featurizer(finalization_flags, hhsearch): + finalization_flags.use_hhsearch = hhsearch + settings = legacy.af2_template_stack_settings() + with patch("alphafold.data.tools.hhsearch.HHSearch") as hh, \ + patch("alphafold.data.tools.hmmsearch.Hmmsearch") as hmm, \ + patch("alphafold.data.templates.HhsearchHitFeaturizer") as hh_features, \ + patch("alphafold.data.templates.HmmsearchHitFeaturizer") as hmm_features: + searcher, featurizer = build_af2_template_stack(settings) + selected_search, selected_features = (hh, hh_features) if hhsearch else (hmm, hmm_features) + assert searcher is selected_search.return_value + assert featurizer is selected_features.return_value + if hhsearch: + hh.assert_called_once_with(binary_path="hhsearch", databases=[settings.pdb70_database_path]) + hmm.assert_not_called() + else: + hmm.assert_called_once_with(binary_path="hmmsearch", hmmbuild_binary_path="hmmbuild", + database_path=settings.pdb_seqres_database_path) + hh.assert_not_called() + assert selected_features.call_args.kwargs == dict( + mmcif_dir=settings.template_mmcif_dir, max_template_date=settings.max_template_date, + max_hits=20, kalign_binary_path="kalign", release_dates_path=None, + obsolete_pdbs_path=settings.obsolete_pdbs_path, + ) + + +@pytest.mark.parametrize("hhsearch", [False, True]) +def test_metadata_contains_only_the_template_resources_used(finalization_flags, hhsearch): + finalization_flags.use_hhsearch = hhsearch + stack = legacy.af2_template_stack_settings() + with patch.object(cli.save_meta_data, "get_meta_dict", return_value={"sentinel": 1}) as metadata: + assert cli.af2_template_metadata(stack) == {"sentinel": 1} + supplied = metadata.call_args.args[0] + assert supplied["kalign_binary_path"] == "kalign" + assert supplied["template_mmcif_dir"] == stack.template_mmcif_dir + if hhsearch: + assert supplied["pdb70_database_path"] == stack.pdb70_database_path + assert "pdb_seqres_database_path" not in supplied + assert "hmmsearch_binary_path" not in supplied + else: + assert supplied["pdb_seqres_database_path"] == stack.pdb_seqres_database_path + assert "pdb70_database_path" not in supplied + assert "hhsearch_binary_path" not in supplied + assert "jackhmmer_binary_path" not in supplied + assert "hhblits_binary_path" not in supplied + + +@pytest.mark.parametrize("backend,hhsearch,required", [ + ("alphafold2", True, "template_pdb70_database_id"), + ("alphafold2", False, "template_seqres_database_id"), + ("alphafold3", True, "template_seqres_database_id"), +]) +def test_template_identity_validation_selects_the_database(finalization_flags, backend, hhsearch, required): + finalization_flags.data_pipeline = backend + finalization_flags.use_hhsearch = hhsearch + assert required_template_flag_names(data_pipeline=backend, use_hhsearch=hhsearch) == ( + required, "template_mmcif_database_id" + ) + require_template_flags(finalization_flags) + setattr(finalization_flags, required, " ") + with pytest.raises(ValueError, match=required): + require_template_flags(finalization_flags) + + +@pytest.mark.parametrize("hhsearch", [False, True]) +def test_af2_finalization_cli_passes_selected_identity_and_requests(finalization_flags, hhsearch): + finalization_flags.use_hhsearch = hhsearch + if hhsearch: + finalization_flags.template_seqres_database_id = None + result = SimpleNamespace(written=(), reused=(), failures=()) + with patch.object(cli, "build_af2_template_stack", return_value=("searcher", "featurizer")), \ + patch.object(cli, "af2_template_metadata", return_value={"software": {}}), \ + patch.object(cli, "Af2FeatureFinalizer") as factory: + factory.return_value.generate.return_value = result + cli.main([]) + settings = factory.call_args.kwargs["settings"] + assert settings.template_searcher == ("hhsearch" if hhsearch else "hmmsearch") + assert settings.template_pdb70_database_id == "pdb70-v1" + assert settings.template_mmcif_database_id == "mmcif-v1" + assert factory.call_args.kwargs["template_searcher"] == "searcher" + [request] = factory.return_value.generate.call_args.args[0] + assert (request.name, request.sequence) == ("query", "ACDE") + + +def test_af3_finalization_cli_keeps_its_seqres_identity(finalization_flags): + finalization_flags.data_pipeline = "alphafold3" + result = SimpleNamespace(written=(), reused=(), failures=()) + with patch.object(legacy, "create_pipeline_af3", return_value="af3-pipeline"), \ + patch.object(legacy, "get_af3_feature_metadata", return_value={}) as metadata, \ + patch.object(cli, "FeatureFinalizer") as factory: + factory.return_value.generate.return_value = result + cli.main([]) + settings = factory.call_args.kwargs["settings"] + assert settings.template_seqres_database_id == "seqres-v1" + assert settings.template_mmcif_database_id == "mmcif-v1" + assert factory.call_args.kwargs["af3_pipeline"] == "af3-pipeline" + assert metadata.call_args.kwargs["skip_msa"] is True + [request] = factory.return_value.generate.call_args.args[0] + assert request.sequence == "ACDE" + + +def test_cli_rejects_missing_pdb70_identity_before_loading_tools(finalization_flags): + finalization_flags.use_hhsearch = True + finalization_flags.template_pdb70_database_id = None + with patch.object(cli, "build_af2_template_stack") as factory: + with pytest.raises(ValueError, match="template_pdb70_database_id"): + cli.main([]) + factory.assert_not_called() + + +def test_cli_reports_per_sequence_failures(finalization_flags): + result = SimpleNamespace(written=(), reused=(), failures=(SimpleNamespace(name="query", error="damaged bundle"),)) + with patch.object(cli, "_finalize_alphafold2", return_value=result): + with pytest.raises(RuntimeError, match=r"query \(damaged bundle\)"): + cli.main([]) + + +@pytest.mark.parametrize("flag", ["skip_msa", "keep_msas", "use_mmseqs2", "path_to_mmt"]) +def test_cli_rejects_incompatible_feature_modes(finalization_flags, flag): + setattr(finalization_flags, flag, "/tmp/mmt" if flag == "path_to_mmt" else True) + with pytest.raises(ValueError, match="cannot be combined"): + cli.main([]) diff --git a/test/unit/test_feature_batch.py b/test/unit/test_feature_batch.py index 76338c50..e1f6bb6f 100644 --- a/test/unit/test_feature_batch.py +++ b/test/unit/test_feature_batch.py @@ -119,6 +119,10 @@ def result_to_msa( del query_db, result_db msa_db.write_text(database.name, encoding="utf-8") + # The fixture's hits carry no insertions and single-token headers, so both + # result2msa passes format them identically and the stitch is a no-op. + result_to_a3m = result_to_msa + def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: output_dir.mkdir(parents=True, exist_ok=True) database_name = msa_db.read_text(encoding="utf-8") @@ -176,18 +180,52 @@ def search( super().search(query_db, database, result_db, work_dir, settings) -class FullHeaderAlignedFastaMmseqs(FakeMmseqsProcess): +class TwoPassMmseqs(FakeMmseqsProcess): + """Formats one hit the way the real pinned MMseqs2 build does, in both passes. + + The hit carries a one-residue insertion (X, between C and D). Mode 2 keeps the + full UniProt header and drops the insertion; mode 5 keeps the insertion and cuts + the header to the accession. Measured, not assumed: see msa_formats. + + This replaces a fixture that fed mode 2 a query row WITH a gap column, on the + belief that mode 2 carries insertions that way. The real build never emits one + -- every row comes back at query width -- so that path never ran on real data. + """ + + def result_to_msa(self, query_db, database, result_db, msa_db) -> None: + del query_db, database, result_db + msa_db.write_text("headers", encoding="utf-8") + + def result_to_a3m(self, query_db, database, result_db, msa_db) -> None: + del query_db, database, result_db + msa_db.write_text("insertions", encoding="utf-8") + def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: - del msa_db output_dir.mkdir(parents=True, exist_ok=True) + insertions = msa_db.read_text(encoding="utf-8") == "insertions" for index, (query_id, sequence) in enumerate(self._queries[query_db]): assert sequence == "ACDE" + hit = ( + ">P12345\nACxDE\n" + if insertions + else ">sp|P12345|KINASE_HUMAN Protein kinase OS=Homo sapiens " + "OX=9606 GN=KIN1\nACDE\n" + ) + (output_dir / f"{index}.fasta").write_text( + f">{query_id}\nACDE\n{hit}", encoding="utf-8" + ) + + +class ReorderedPassesMmseqs(TwoPassMmseqs): + """The two passes disagree about which hit is which, as a future MMseqs2 might.""" + + def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: + output_dir.mkdir(parents=True, exist_ok=True) + insertions = msa_db.read_text(encoding="utf-8") == "insertions" + for index, (query_id, _) in enumerate(self._queries[query_db]): + first, second = ("ACDE", "ACDQ") if insertions else ("ACDQ", "ACDE") (output_dir / f"{index}.fasta").write_text( - f">{query_id} query description\n" - "AC-DE\n" - ">sp|P12345|KINASE_HUMAN Protein kinase OS=Homo sapiens " - "OX=9606 GN=KIN1\n" - "ACXDE\n", + f">{query_id}\nACDE\n>sp|P1|A_HUMAN\n{first}\n>sp|P2|B_YEAST\n{second}\n", encoding="utf-8", ) @@ -247,6 +285,31 @@ def test_subprocess_adapter_requests_aligned_fasta_output(tmp_path): assert command[command.index("--msa-format-mode") + 1] == "2" +def test_subprocess_adapter_requests_a3m_for_the_insertion_pass(tmp_path): + # Mode 5 is the only result2msa format that keeps insertions. + binary = tmp_path / "mmseqs" + arguments = Path(f"{binary}.arguments") + binary.write_text( + '#!/bin/sh\nprintf \'%s\\n\' "$@" > "${0}.arguments"\n', + encoding="utf-8", + ) + binary.chmod(0o755) + database = DatabaseSpec( + name="uniprot", path=tmp_path / "uniprot", identifier="fixture" + ) + + SubprocessMmseqsProcess(binary).result_to_a3m( + tmp_path / "query", + database, + tmp_path / "result", + tmp_path / "msa", + ) + + command = arguments.read_text(encoding="utf-8").splitlines() + assert command[0] == "result2msa" + assert command[command.index("--msa-format-mode") + 1] == "5" + + def test_gpu_search_does_not_pass_ignored_sensitivity_option(tmp_path): binary = tmp_path / "mmseqs" arguments = Path(f"{binary}.arguments") @@ -570,10 +633,15 @@ def test_downstream_af3_failure_preserves_a_valid_msa_bundle(tmp_path): assert bundle.exists() -def test_aligned_fasta_conversion_preserves_taxon_header_and_insertions(tmp_path): +def test_stitched_alignment_keeps_taxon_header_and_insertions(tmp_path): + """Both halves reach AlphaFold 3 -- which neither result2msa pass gives alone. + + The header decides species pairing; the insertion is what mode 2 used to + discard for 86% of real uniprot hits. + """ batch = FeatureBatch( settings=_settings(tmp_path), - mmseqs_process=FullHeaderAlignedFastaMmseqs(), + mmseqs_process=TwoPassMmseqs(), af3_pipeline=PassthroughAf3Pipeline(), ) @@ -591,6 +659,78 @@ def test_aligned_fasta_conversion_preserves_taxon_header_and_insertions(tmp_path assert "\nACxDE\n" in paired_msa +def test_passes_that_disagree_fail_the_request_rather_than_mislabel_hits(tmp_path): + """A positional join that silently went wrong would label P1's sequence as P2's. + + On the paired database that means pairing chains by the wrong species: a wrong + answer that looks entirely plausible. It has to fail, loudly and per request, + and publish nothing. + """ + settings = _settings(tmp_path) + batch = FeatureBatch( + settings=settings, + mmseqs_process=ReorderedPassesMmseqs(), + af3_pipeline=PassthroughAf3Pipeline(), + ) + + result = batch.generate([FeatureRequest(name="alpha", sequence="ACDE")]) + + assert [failure.name for failure in result.failures] == ["alpha"] + assert "no longer in the same order" in result.failures[0].error + assert not (settings.msa_output_dir / "alpha_mmseqs_msa.json").exists() + assert not (tmp_path / "features" / "alpha_af3_input.json").exists() + + +def test_bundle_records_how_many_rows_each_database_contributed(tmp_path): + """AlphaFold 2 searches templates from uniref90 alone and caps each database + separately, so the merged alignment is only usable if its boundaries survive.""" + settings = _settings(tmp_path) + FeatureBatch( + settings=settings, + mmseqs_process=FakeMmseqsProcess(), + af3_pipeline=PassthroughAf3Pipeline(), + ).generate([FeatureRequest(name="alpha", sequence="ACDEFG")]) + + bundle = json.loads( + (settings.msa_output_dir / "alpha_mmseqs_msa.json").read_text(encoding="utf-8") + ) + assert bundle["schemaVersion"] == 3 + spans = bundle["unpairedDatabaseRows"] + assert [span["name"] for span in spans] == ["uniref90", "mgnify", "small_bfd"] + # The fixture gives each database one distinct hit, and the spans must account + # for every row of the merged alignment except the query. + assert [span["rows"] for span in spans] == [1, 1, 1] + assert sum(span["rows"] for span in spans) == bundle["unpairedDepth"] - 1 + + # And each span really is that database's rows, in order. + rows = bundle["unpairedMsa"].splitlines()[3::2] + assert [row[0] for row in rows] == ["V", "R", "N"] + + +def test_bundle_whose_row_spans_do_not_add_up_is_searched_again(tmp_path): + """A wrong count does not fail when sliced -- it hands AlphaFold 2 another + database's rows as uniref90. So a bundle that does not add up is not reused.""" + settings = _settings(tmp_path) + request = FeatureRequest(name="alpha", sequence="ACDEFG") + FeatureBatch( + settings=settings, + mmseqs_process=FakeMmseqsProcess(), + af3_pipeline=PassthroughAf3Pipeline(), + ).generate([request]) + bundle_path = settings.msa_output_dir / "alpha_mmseqs_msa.json" + bundle = json.loads(bundle_path.read_text(encoding="utf-8")) + bundle["unpairedDatabaseRows"][0]["rows"] += 1 + bundle_path.write_text(json.dumps(bundle), encoding="utf-8") + + searching = FakeMmseqsProcess() + result = MsaBatch( + settings=_msa_settings(settings), mmseqs_process=searching + ).generate([request]) + + assert [artifact.name for artifact in result.written] == ["alpha"] + assert result.reused == () + + def test_matching_artifact_is_reused_without_external_search(tmp_path): settings = _settings(tmp_path) pipeline = _native_pipeline_with_no_template_hits(tmp_path) diff --git a/test/unit/test_feature_batch_rna.py b/test/unit/test_feature_batch_rna.py index 5202e432..37feb58e 100644 --- a/test/unit/test_feature_batch_rna.py +++ b/test/unit/test_feature_batch_rna.py @@ -29,6 +29,7 @@ FeatureRequest, MsaBatch, MsaBatchSettings, + SearchedMsas, SubprocessMmseqsProcess, feature_requests_from_fastas, ) @@ -137,6 +138,10 @@ def result_to_msa(self, query_db, database, result_db, msa_db) -> None: del query_db, result_db msa_db.write_text(database.name, encoding="utf-8") + # The fixture's hits carry no insertions and single-token headers, so both + # result2msa passes format them identically and the stitch is a no-op. + result_to_a3m = result_to_msa + def unpack_msa(self, query_db: Path, msa_db: Path, output_dir: Path) -> None: output_dir.mkdir(parents=True, exist_ok=True) database_name = msa_db.read_text(encoding="utf-8") @@ -245,17 +250,28 @@ def test_rna_databases_are_the_three_alphafold3_searches_in_its_merge_order(): # -------------------------------------------------------------------------------- -def test_protein_cache_signature_is_exactly_what_it_was_before_rna_existed(tmp_path): - """Pinned literally: changing it silently invalidates every cached protein MSA.""" +def test_protein_cache_signature_is_pinned(tmp_path): + """Pinned literally: changing it silently invalidates every cached protein MSA. + + It last moved, deliberately, when insertions were recovered (schema 4 -> 5, + and ``msa_format`` added). Bundles written before that came from mode 2 alone + and carry no insertions -- 86% of uniprot hits lost theirs on a real query -- + so reusing them would have kept the defect. The only cache that existed at + the time was two bundles of e2e test data. Move it again only as deliberately. + """ batch = MsaBatch( settings=_msa_settings(_settings(tmp_path)), mmseqs_process=FakeMmseqsProcess(), ) assert batch._cache_signature(PROTEIN) == { - "schema_version": 4, + "schema_version": 5, "mmseqs_identity": "mmseqs-fixture-1", "search_mode": "gpu", + "msa_format": { + "headers": "result2msa mode 2", + "sequences": "result2msa mode 5", + }, "e_value": 1e-4, "unpaired_databases": [ { @@ -306,12 +322,12 @@ def test_a_protein_bundle_records_no_molecule_type_so_old_bundles_still_match(tm ) protein = batch._msa_payload( - FeatureRequest(name="alpha", sequence="ACDE"), ">query\nACDE\n", ">query\nACDE\n" + FeatureRequest(name="alpha", sequence="ACDE"), + SearchedMsas(unpaired=">query\nACDE\n", paired=">query\nACDE\n"), ) rna = batch._msa_payload( FeatureRequest(name="beta", sequence="ACGU", molecule_type=RNA), - ">query\nACGU\n", - "", + SearchedMsas(unpaired=">query\nACGU\n", paired=""), ) assert "moleculeType" not in protein @@ -323,6 +339,7 @@ def test_a_protein_bundle_records_no_molecule_type_so_old_bundles_still_match(tm "pairedMsa", "unpairedDepth", "pairedDepth", + "unpairedDatabaseRows", "provenance", ] assert rna["moleculeType"] == RNA @@ -763,7 +780,9 @@ def test_an_rna_query_reaches_mmseqs_spelled_as_dna(tmp_path, monkeypatch): batch = MsaBatch(settings=settings, mmseqs_process=process) monkeypatch.setattr( - feature_batch_module, "_aligned_fasta_to_a3m", lambda fasta, query, kind: fasta + feature_batch_module, + "_stitched_to_a3m", + lambda records, query, kind: "".join(f">{d}\n{s}\n" for d, s in records), ) batch._search_chunk(["ACGUUU"], RNA) @@ -781,7 +800,9 @@ def test_a_protein_query_is_handed_to_mmseqs_unchanged(tmp_path, monkeypatch): batch = MsaBatch(settings=settings, mmseqs_process=process) monkeypatch.setattr( - feature_batch_module, "_aligned_fasta_to_a3m", lambda fasta, query, kind: fasta + feature_batch_module, + "_stitched_to_a3m", + lambda records, query, kind: "".join(f">{d}\n{s}\n" for d, s in records), ) batch._search_chunk(["ACDEFGU"], PROTEIN) diff --git a/test/unit/test_light_import_invariant.py b/test/unit/test_light_import_invariant.py index ce1181ea..c6bfd6df 100644 --- a/test/unit/test_light_import_invariant.py +++ b/test/unit/test_light_import_invariant.py @@ -54,3 +54,48 @@ def test_the_light_path_pulls_in_neither_alphafold_nor_jax(module): "MMseqs2 search; importing JAX there preallocates GPU memory. Import it " "inside the function that needs it instead." ) + + +# Importing the module was never the hard part. Converting a search result used +# `alphafold3.cpp.msa_conversion`, so the stage imported cleanly in the AlphaFold 2 +# image -- which installs AlphaPulldown without the `alphafold3` extra -- and then +# died on the first result. Exercise the conversion itself, not just the import. +RESULT_PROBE = """ +import importlib, sys +feature_batch = importlib.import_module("alphapulldown.feature_batch") +from alphapulldown.utils.msa_formats import stitch_headers_and_insertions +headers = [ + ("query_0", "MKTAYIAKQRQ"), + ("sp|P00001|EXACT_HUMAN exact OS=Homo sapiens OX=9606", "MKTAYIAKQRQ"), + ("tr|P00003|DELETE_YEAST deletion OS=Saccharomyces OX=4932", "MKT---AKQRQ"), +] +insertions = [ + ("query_0", "MKTAYIAKQRQ"), + ("P00001", "MKTAYIAKQRQ"), + ("P00003", "MKT---AKwwQRQ"), +] +a3m = feature_batch._stitched_to_a3m( + stitch_headers_and_insertions(headers, insertions), "MKTAYIAKQRQ" +) +assert "sp|P00001|EXACT_HUMAN" in a3m, "full headers must survive conversion" +assert "MKT---AKwwQRQ" in a3m, "deletions and insertions must survive conversion" +leaked = sorted( + name for name in sys.modules + if any(name == f or name.startswith(f + ".") for f in {forbidden!r}) +) +print(",".join(leaked)) +""" + + +def test_converting_a_search_result_pulls_in_neither_alphafold_nor_jax(): + completed = subprocess.run( + [sys.executable, "-c", RESULT_PROBE.format(forbidden=FORBIDDEN)], + capture_output=True, + text=True, + ) + assert completed.returncode == 0, completed.stderr[-2000:] + leaked = [name for name in completed.stdout.strip().split(",") if name] + assert not leaked, ( + f"converting a search result now imports {leaked}. The MSA stage has to " + "run in the AlphaFold 2 image, which has no AlphaFold 3 at all." + ) diff --git a/test/unit/test_mmseqs_process_options.py b/test/unit/test_mmseqs_process_options.py new file mode 100644 index 00000000..1313ba43 --- /dev/null +++ b/test/unit/test_mmseqs_process_options.py @@ -0,0 +1,174 @@ +"""Process-level MMseqs2 options, and which of them may touch the cache identity. + +Deliberately free of any AlphaFold 3 import: the search stage runs in the +AlphaFold 2 image too, and a module-level skip there would report success while +silently testing nothing. The equivalent assertions in ``test_feature_batch.py`` +cannot run in that image because that module needs AlphaFold 3 for the finalizer. +""" + +from __future__ import annotations + +import dataclasses +from pathlib import Path + +import pytest + +from alphapulldown.feature_batch import ( + DatabaseSpec, + MsaBatch, + MsaBatchSettings, + SubprocessMmseqsProcess, +) + + +PROTEIN_DATABASES = ("uniref90", "mgnify", "small_bfd") + + +@pytest.fixture +def recording_binary(tmp_path: Path) -> tuple[Path, Path]: + """A stand-in executable that records the arguments it was called with.""" + binary = tmp_path / "mmseqs" + binary.write_text( + '#!/bin/sh\nprintf \'%s\\n\' "$@" > "${0}.arguments"\n', encoding="utf-8" + ) + binary.chmod(0o755) + return binary, Path(f"{binary}.arguments") + + +def _settings(tmp_path: Path) -> MsaBatchSettings: + return MsaBatchSettings( + output_dir=tmp_path / "out", + temp_dir=tmp_path / "tmp", + unpaired_databases=tuple( + DatabaseSpec(name=name, path=tmp_path / name, identifier=f"{name}-fixture") + for name in PROTEIN_DATABASES + ), + paired_database=DatabaseSpec( + name="uniprot", path=tmp_path / "uniprot", identifier="uniprot-fixture" + ), + max_sequences_per_batch=8, + max_residues_per_batch=10_000, + threads=4, + ) + + +def _database(tmp_path: Path) -> DatabaseSpec: + return DatabaseSpec( + name="uniref90", path=tmp_path / "uniref90", identifier="fixture" + ) + + +def test_db_load_mode_reaches_the_search(tmp_path: Path, recording_binary): + binary, arguments = recording_binary + SubprocessMmseqsProcess(binary, db_load_mode=2).search( + tmp_path / "query", + _database(tmp_path), + tmp_path / "result", + tmp_path / "work", + _settings(tmp_path), + ) + command = arguments.read_text(encoding="utf-8").splitlines() + assert command[command.index("--db-load-mode") + 1] == "2" + + +def test_db_load_mode_reaches_result_to_msa(tmp_path: Path, recording_binary): + # Both commands read the target database, so both must honour the setting; + # passing it only to the search would leave the peak memory it exists to + # lower untouched in the second half of the stage. + binary, arguments = recording_binary + SubprocessMmseqsProcess(binary, db_load_mode=2).result_to_msa( + tmp_path / "query", + _database(tmp_path), + tmp_path / "result", + tmp_path / "msa", + ) + command = arguments.read_text(encoding="utf-8").splitlines() + assert command[command.index("--db-load-mode") + 1] == "2" + + +@pytest.mark.parametrize("operation", ("search", "result_to_msa")) +def test_the_option_is_absent_when_unset( + tmp_path: Path, recording_binary, operation: str +): + """Unset must mean "say nothing", so MMseqs2 keeps choosing for itself.""" + binary, arguments = recording_binary + process = SubprocessMmseqsProcess(binary) + if operation == "search": + process.search( + tmp_path / "query", + _database(tmp_path), + tmp_path / "result", + tmp_path / "work", + _settings(tmp_path), + ) + else: + process.result_to_msa( + tmp_path / "query", + _database(tmp_path), + tmp_path / "result", + tmp_path / "msa", + ) + assert "--db-load-mode" not in arguments.read_text().splitlines() + + +def test_db_load_mode_stays_out_of_the_cache_signature(tmp_path: Path): + """It changes memory behaviour, never the alignment. + + If it reached the signature, turning it on to survive a tight allocation + would discard every alignment already computed -- a re-search costing hours + per shard to produce byte-identical output. Asserted on two real adapters + that differ in exactly this one setting. + """ + binary = tmp_path / "mmseqs" + binary.write_text("#!/bin/sh\necho mmseqs-fixture-version\n", encoding="utf-8") + binary.chmod(0o755) + settings = _settings(tmp_path) + + plain = MsaBatch( + settings=settings, mmseqs_process=SubprocessMmseqsProcess(binary) + ) + mapped = MsaBatch( + settings=settings, + mmseqs_process=SubprocessMmseqsProcess(binary, db_load_mode=2), + ) + assert plain._cache_signature() == mapped._cache_signature() + + # The comparison above is only meaningful if a setting that DOES change the + # alignment moves the signature. GPU and CPU search are such a setting. + on_cpu = MsaBatch( + settings=settings, + mmseqs_process=SubprocessMmseqsProcess(binary, gpu=False), + ) + assert plain._cache_signature() != on_cpu._cache_signature() + + +def test_iterations_reach_protein_searches_but_never_nucleotide_ones( + tmp_path: Path, recording_binary +): + """Iterative profile search is protein-only. Measured on the pinned build, + --num-iterations 3 on a nucleotide search exits 1, so raising the setting + used to fail every RNA shard.""" + binary, arguments = recording_binary + settings = dataclasses.replace(_settings(tmp_path), num_iterations=3) + process = SubprocessMmseqsProcess(binary) + + process.search( + tmp_path / "query", + _database(tmp_path), + tmp_path / "result", + tmp_path / "work", + settings, + ) + protein = arguments.read_text(encoding="utf-8").splitlines() + assert protein[protein.index("--num-iterations") + 1] == "3" + + rfam = DatabaseSpec( + name="rfam", path=tmp_path / "rfam", identifier="rfam-fixture", + molecule_type="rna", + ) + process.search( + tmp_path / "query", rfam, tmp_path / "result", tmp_path / "work", settings + ) + nucleotide = arguments.read_text(encoding="utf-8").splitlines() + assert "--num-iterations" not in nucleotide + assert nucleotide[nucleotide.index("--search-type") + 1] == "3" diff --git a/test/unit/test_msa_bundle_validation.py b/test/unit/test_msa_bundle_validation.py new file mode 100644 index 00000000..f5799e2a --- /dev/null +++ b/test/unit/test_msa_bundle_validation.py @@ -0,0 +1,121 @@ +"""Validate persisted alignment data before finalization can trust it.""" + +import json + +import pytest + +from alphapulldown.feature_batch import ( + FeatureRequest, + RNA, + RNA_DATABASE_NAMES, + read_msa_bundle, +) + + +@pytest.fixture +def bundle(tmp_path): + payload = { + "sequence": "ACDE", + "provenance": {"fixture": "bundle-validation"}, + "unpairedMsa": ">query\nACDE\n>hit\nACDF\n", + "pairedMsa": ">query\nACDE\n", + "unpairedDatabaseRows": [ + {"name": "uniref90", "rows": 1}, + {"name": "mgnify", "rows": 0}, + {"name": "small_bfd", "rows": 0}, + ], + } + return tmp_path / "alpha_mmseqs_msa.json", payload + + +@pytest.mark.parametrize( + "damage", ("missing_role", "duplicate_role", "unknown_role", "empty_paired", "empty_unpaired") +) +def test_unusable_alignment_data_is_deleted_before_finalization(bundle, damage): + path, payload = bundle + if damage == "missing_role": + payload["unpairedDatabaseRows"].pop() + elif damage == "duplicate_role": + # Keep every required role and the correct total, but duplicate UniRef90. + # A decoder keyed only by name would silently replace its nonempty span. + payload["unpairedDatabaseRows"].append({"name": "uniref90", "rows": 0}) + elif damage == "unknown_role": + payload["unpairedDatabaseRows"][-1]["name"] = "unknown" + elif damage == "empty_paired": + payload["pairedMsa"] = "" + else: + payload["unpairedMsa"] = "" + payload["unpairedDatabaseRows"][0]["rows"] = 0 + path.write_text(json.dumps(payload)) + + with pytest.raises(ValueError): + read_msa_bundle( + path.parent, FeatureRequest("alpha", "ACDE"), require_row_spans=True + ) + + assert not path.exists(), "An unusable bundle must be removed so the shard repairs it" + + +def test_valid_protein_bundle_keeps_its_query_only_pairing_alignment(bundle): + path, payload = bundle + path.write_text(json.dumps(payload)) + + result = read_msa_bundle( + path.parent, FeatureRequest("alpha", "ACDE"), require_row_spans=True + ) + + assert result == payload + assert path.exists() + + +def test_rna_bundle_has_no_paired_alignment_and_uses_its_own_database_roles(bundle): + path, payload = bundle + payload.update( + sequence="ACGU", moleculeType=RNA, + unpairedMsa=">query\nACGU\n", pairedMsa="", + unpairedDatabaseRows=[{"name": name, "rows": 0} for name in RNA_DATABASE_NAMES], + ) + path.write_text(json.dumps(payload)) + + result = read_msa_bundle( + path.parent, FeatureRequest("alpha", "ACGU", RNA), require_row_spans=True + ) + + assert result == payload + assert path.exists() + + +def test_template_search_failure_preserves_a_valid_af2_msa_bundle(bundle): + pytest.importorskip("alphafold.data.pipeline", reason="needs AlphaFold 2") + from alphapulldown.af2_feature_finalizer import ( + Af2FeatureFinalizationSettings, + Af2FeatureFinalizer, + ) + + class FailingTemplateSearcher: + input_format = "sto" + output_format = "sto" + + def query(self, text): + raise RuntimeError("template database is temporarily unavailable") + + path, payload = bundle + encoded = json.dumps(payload) + path.write_text(encoded) + finalizer = Af2FeatureFinalizer( + settings=Af2FeatureFinalizationSettings( + output_dir=path.parent / "features", msa_input_dir=path.parent, + max_template_date="2050-01-01", template_seqres_database_id="seqres-v1", + template_mmcif_database_id="mmcif-v1", + ), + template_searcher=FailingTemplateSearcher(), + template_featurizer=None, + ) + + result = finalizer.generate([FeatureRequest("alpha", "ACDE")]) + + assert not result.written + assert [(failure.name, failure.error) for failure in result.failures] == [ + ("alpha", "template database is temporarily unavailable") + ] + assert path.read_text() == encoded diff --git a/test/unit/test_msa_formats.py b/test/unit/test_msa_formats.py new file mode 100644 index 00000000..4eb140f5 --- /dev/null +++ b/test/unit/test_msa_formats.py @@ -0,0 +1,171 @@ +"""Joining two MMseqs2 formats into one A3M with headers AND insertions.""" + +from __future__ import annotations + +from pathlib import Path +import re +import subprocess +import sys + +import pytest + +from alphapulldown.utils.msa_formats import ( + StitchMismatch, + stitch_headers_and_insertions, + strip_insertions, +) + + +def test_conversion_does_not_import_alphafold(): + """The whole point: this must work in the AlphaFold 2 image. + + Checked in a subprocess, because the test session may already have imported + AlphaFold for other modules and would mask exactly what is being measured. + """ + probe = ( + "import sys;" + "from alphapulldown.utils.msa_formats import stitch_headers_and_insertions as f;" + "f([('q', 'MKTAYI')], [('q', 'MKTAYI')]);" + "print(','.join(n for n in sys.modules if n.startswith('alphafold')))" + ) + completed = subprocess.run( + [sys.executable, "-c", probe], capture_output=True, text=True, check=True + ) + assert completed.stdout.strip() == "" + + +def test_strip_insertions_leaves_one_column_per_query_position(): + # Lowercase residues are insertions; gaps and match residues are columns. + assert strip_insertions("MKTwwAY-I") == "MKTAY-I" + + +def test_stitch_takes_headers_from_one_pass_and_insertions_from_the_other(): + headers = [("query", "MKTAYI"), ("sp|P1|A_HUMAN full header", "MKTAYI")] + insertions = [("query", "MKTAYI"), ("P1", "MKTwwAYI")] + assert stitch_headers_and_insertions(headers, insertions) == [ + ("query", "MKTAYI"), + ("sp|P1|A_HUMAN full header", "MKTwwAYI"), + ] + + +def test_stitch_refuses_rows_that_disagree(): + """A silent positional join here would pair a header with another hit's + sequence -- for the paired database, pairing chains by the wrong species.""" + headers = [("query", "MKTAYI"), ("sp|P1|A_HUMAN", "MKTAYI")] + reordered = [("query", "MKTAYI"), ("P2", "MKTAYQ")] + with pytest.raises(StitchMismatch, match="no longer in the same order"): + stitch_headers_and_insertions(headers, reordered) + + +def test_stitch_refuses_differing_row_counts(): + with pytest.raises(StitchMismatch, match="different row counts"): + stitch_headers_and_insertions([("query", "MKT")], []) + + +def _read_records(path: Path) -> list[tuple[str, str]]: + records, description, parts = [], None, [] + for line in path.read_text(encoding="utf-8").splitlines(): + if line.startswith(">"): + if description is not None: + records.append((description, "".join(parts))) + description, parts = line[1:], [] + elif description is not None: + parts.append(line) + if description is not None: + records.append((description, "".join(parts))) + return records + + +REAL_MODE2 = Path(__file__).parent / "data" / "small_bfd.mode2.txt" +REAL_MODE5 = Path(__file__).parent / "data" / "small_bfd.mode5.txt" + + +@pytest.mark.skipif( + not (REAL_MODE2.exists() and REAL_MODE5.exists()), + reason="real MMseqs2 output fixtures are not checked in", +) +def test_stitch_holds_on_real_mmseqs_output(): + """The synthetic cases prove the logic; this proves the assumption. + + Fixtures are the two passes over one real search of a 586-residue query + against small_bfd, produced by the pinned MMseqs2 build. + + Note which database this is. How much a header loses in mode 5 depends on the + FASTA it was built from: small_bfd headers are a single token + (``A0A163VT74_9BACL``) and survive intact, so the stitch changes only the + sequences here. It is uniprot that loses the species -- + ``sp|P83570|GWA_SEPOF …`` becomes a bare ``P83570`` -- and uniprot is exactly + where species decides chain pairing. The insertion half of the join is what + this fixture exercises; ``test_stitch_recovers_uniprot_species_headers`` + covers the other half. + """ + headers = _read_records(REAL_MODE2) + insertions = _read_records(REAL_MODE5) + stitched = stitch_headers_and_insertions(headers, insertions) + + assert len(stitched) == len(headers) > 1 + assert [description for description, _ in stitched] == [ + description for description, _ in headers + ] + assert [sequence for _, sequence in stitched] == [ + sequence for _, sequence in insertions + ] + # The point of the exercise: insertions the header pass discarded are back. + recovered = sum( + 1 for _, sequence in stitched for residue in sequence if residue.islower() + ) + assert recovered > 0, "insertions must survive the stitch" + assert not any( + residue.islower() for _, sequence in headers for residue in sequence + ), "the header pass is expected to carry no insertions at all" + + +UNIPROT_MODE2 = Path(__file__).parent / "data" / "uniprot.mode2.txt" +UNIPROT_MODE5 = Path(__file__).parent / "data" / "uniprot.mode5.txt" + + +@pytest.mark.skipif( + not (UNIPROT_MODE2.exists() and UNIPROT_MODE5.exists()), + reason="real uniprot MMseqs2 output fixtures are not checked in", +) +def test_stitch_recovers_uniprot_species_headers(): + """The half that decides whether multimer pairing works at all. + + AlphaFold 2 reads the species mnemonic out of ``sp|ACC|NAME_SPECIES``. Mode 5 + reduces that to ``ACC``, so an alignment built from it alone would pair no + chains; the stitched alignment must carry the parseable form. + """ + headers = _read_records(UNIPROT_MODE2) + insertions = _read_records(UNIPROT_MODE5) + stitched = stitch_headers_and_insertions(headers, insertions) + + # Mirrors alphafold.data.msa_identifiers._UNIPROT_PATTERN, which is what + # actually decides whether a row can be paired. Reproduced rather than + # imported because this module must stay free of AlphaFold; the authoritative + # check against the real function belongs with the AF2 finalizer tests. + uniprot = re.compile( + r"^(?:tr|sp)\|[A-Za-z0-9]{6,10}(?:_\d)?\|[A-Za-z0-9]+_([A-Za-z0-9]{1,5})" + r"(?:_\d+)?$" + ) + + def species(records): + found = set() + for description, _ in records: + match = uniprot.match(description.split()[0]) + if match: + found.add(match.group(1)) + return found + + stitched_species = species(stitched) + assert len(stitched_species) > 1, ( + "the stitched alignment must yield species mnemonics; without them " + "AlphaFold 2 pairs no chains at all" + ) + assert species(insertions) == set(), ( + "the insertion pass is expected to yield none, which is why it is stitched" + ) + assert species(headers) == stitched_species + assert ( + sum(1 for _, sequence in stitched for residue in sequence if residue.islower()) + > 0 + ) diff --git a/test/unit/test_msa_quality.py b/test/unit/test_msa_quality.py index d69551f3..4de6ef2b 100644 --- a/test/unit/test_msa_quality.py +++ b/test/unit/test_msa_quality.py @@ -66,3 +66,82 @@ def test_compare_directories_rejects_unpaired_artifact_sets(tmp_path): with pytest.raises(ValueError, match="missing from candidate"): compare_directories(reference, candidate) + + +def _af2_pickle(path, sequence, msa_rows, *, deletions=None, species=(), templates=()): + """An AlphaFold 2 feature pickle, as far as the comparison reads one. + + Pickles the lightweight stand-in, so this needs no AlphaFold import. + """ + import pickle + + import numpy as np + + from alphapulldown.utils.af2_to_af3_msa import AF2_ID_TO_A3M + from alphapulldown.utils.lightweight_pickles import LightweightMonomericObject + + msa = np.array([[AF2_ID_TO_A3M.index(r) for r in row] for row in msa_rows], + dtype=np.int32) + feature_dict = { + "msa": msa, + "deletion_matrix_int": ( + np.asarray(deletions) if deletions is not None else np.zeros_like(msa) + ), + "msa_all_seq": msa[: 1 + len(species)], + "msa_species_identifiers_all_seq": np.array( + [b"", *[s.encode() for s in species]], dtype=object + ), + "template_domain_names": np.array( + [t.encode() for t in templates] or [b""], dtype=object + ), + } + monomer = LightweightMonomericObject( + description=path.stem, sequence=sequence, feature_dict=feature_dict + ) + path.write_bytes(pickle.dumps(monomer)) + + +def test_af2_comparison_measures_what_each_pickle_gives_the_model(tmp_path): + from alphapulldown.scripts.compare_msa_backends import ( + compare_af2_directories, + summarize_af2, + ) + + reference, candidate = tmp_path / "native", tmp_path / "local" + reference.mkdir() + candidate.mkdir() + _af2_pickle(reference / "alpha.pkl", "ACDEFG", ["ACDEFG", "ACDEFW", "ACDEWG"], + deletions=[[0] * 6, [0, 2, 0, 0, 0, 0], [0] * 6], + species=("HUMAN", "MOUSE"), templates=("1abc_A",)) + _af2_pickle(candidate / "alpha.pkl", "ACDEFG", ["ACDEFG", "ACDEFW"], + species=("HUMAN",)) + + [row] = compare_af2_directories(reference, candidate) + + assert row["reference"]["unpaired"]["depth"] == 3 + assert row["candidate"]["unpaired"]["depth"] == 2 + assert row["reference"]["rows_with_insertions"] == 1 + assert row["candidate"]["rows_with_insertions"] == 0 + assert row["reference"]["paired_species"] == 2 + assert row["candidate"]["paired_species"] == 1 + assert row["reference"]["template_count"] == 1 + # AlphaFold 2's empty-template placeholder is not a template. + assert row["candidate"]["template_count"] == 0 + assert summarize_af2([row])["mean_candidate_paired_species"] == 1 + + +def test_af2_comparison_refuses_unpaired_or_mismatched_sets(tmp_path): + from alphapulldown.scripts.compare_msa_backends import compare_af2_directories + + reference, candidate = tmp_path / "native", tmp_path / "local" + reference.mkdir() + candidate.mkdir() + _af2_pickle(reference / "alpha.pkl", "ACDEFG", ["ACDEFG"]) + _af2_pickle(candidate / "beta.pkl", "ACDEFG", ["ACDEFG"]) + with pytest.raises(ValueError, match="differ"): + compare_af2_directories(reference, candidate) + + (candidate / "beta.pkl").unlink() + _af2_pickle(candidate / "alpha.pkl", "ACDEFW", ["ACDEFW"]) + with pytest.raises(ValueError, match="Sequence mismatch"): + compare_af2_directories(reference, candidate) diff --git a/workflows/mmseqs2-gpu.md b/workflows/mmseqs2-gpu.md index ff2547ce..7395bf0a 100644 --- a/workflows/mmseqs2-gpu.md +++ b/workflows/mmseqs2-gpu.md @@ -52,6 +52,11 @@ RNA databases from `--data_dir`. Final artifact provenance therefore also includes `--max_template_date`, `--template_seqres_database_id`, and `--template_mmcif_database_id`. +AF2 finalization with `--use_hhsearch` requires `--template_pdb70_database_id` +instead of the unused seqres identity. Update the selected immutable identity +when its database is rebuilt, including rebuilds at the same path. Only features +are invalidated; the search-stage MSA bundles remain reusable. + GPU database memory can be substantial. Prefer fast node-local storage and an Ampere-or-newer GPU. A database larger than VRAM can stream from host RAM, but requires enough host memory and runs below peak throughput. @@ -70,9 +75,23 @@ knob and does not include one in cache provenance. ## MSA and template behavior For each chunk, one query database is reused for UniRef90, MGnify, small BFD, -and paired UniProt searches. Aligned FASTA is converted to A3M while retaining -insertions and complete UniProt descriptions, including taxonomy metadata. -Unpaired hits from all three databases are merged and deduplicated. +and paired UniProt searches. Each search result is formatted twice, because no +single `result2msa` format carries both things an alignment needs: mode 2 keeps +complete UniProt descriptions, including the species AlphaFold pairs chains by, +but drops every insertion; mode 5 keeps the insertions but cuts the header to +the accession. The two are joined row by row, and the join is verified on every +row rather than trusted. The second pass costs about 16 ms per hit. + +MSA bundles written before this (bundle schema 2, provenance schema 4) came +from mode 2 alone and carry no insertions, so the deletion matrix AlphaFold +derived from them was all zeros; against a real query, 81.7% of small BFD hits +and 86.4% of UniProt hits had insertions that were lost. The provenance change +means such bundles are never reused: they are searched again. + +Unpaired hits from all three databases are merged and deduplicated, and the +bundle records how many rows each database contributed. AlphaFold 3 does not +need that, but an AlphaFold 2 consumer does: it builds its template profile from +UniRef90 alone and caps each database separately. The finalizer passes that merged unpaired MSA to native AF3 with `templates` unset. This matches AF3's own pipeline: it merges UniRef90, small-BFD, and MGnify