From 892ffa65cf7a166a170112c00d4fc08bf62b827a Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 6 Apr 2026 17:15:22 -0500 Subject: [PATCH 01/28] fix: adds PDBFixer memory isolation and auto-repair logic --- frustratometer/classes/Structure.py | 56 +- frustratometer/pdb/fix.py | 115 ++- tests/data/2GHY.pdb | 1274 +++++++++++++++++++++++++++ tests/test_structure.py | 87 ++ 4 files changed, 1483 insertions(+), 49 deletions(-) create mode 100644 tests/data/2GHY.pdb create mode 100644 tests/test_structure.py diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index da820a75..41b7f3d7 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -6,16 +6,19 @@ from typing import Union from pathlib import Path import tempfile +import logging import warnings __all__ = ['Structure'] +logger = logging.getLogger(__name__) + residue_names=[] class Structure: def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_selection: str = None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, - distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb:bool = True)->object: + distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None)->object: """ Generates structure object. Both PDB and CIF format files are accepted as input. @@ -52,8 +55,12 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s pdb_directory: str Directory where repaired pdb will be stored. Defaults to the system temporary directory. - repair_pdb: bool - If True, provided pdb file will be repaired with missing residues inserted and heteroatoms removed. + repair_pdb: bool or None + If True, the PDB file is always repaired (missing residues filled, heteroatoms removed). + If False, no repair is attempted. + If None (default), the structure is built without repair first; if the + sequence length does not match the distance matrix, repair is attempted + automatically. Note that a pdb file will be produced, regardless of input file format. Returns @@ -63,6 +70,39 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s if pdb_directory is None: pdb_directory = Path(tempfile.gettempdir()) + if repair_pdb is None: + # Auto-detect: try without repair, retry with repair on validation failure + try: + self._init_structure(pdb_file, chain, seq_selection, aligned_sequence, + filtered_aligned_sequence, distance_matrix_method, + pdb_directory, repair_pdb=False) + self._validate_structure() + except Exception as e: + logger.info("Structure validation failed without repair (%s), retrying with repair_pdb=True", e) + self._init_structure(pdb_file, chain, seq_selection, aligned_sequence, + filtered_aligned_sequence, distance_matrix_method, + pdb_directory, repair_pdb=True) + self._validate_structure() + else: + self._init_structure(pdb_file, chain, seq_selection, aligned_sequence, + filtered_aligned_sequence, distance_matrix_method, + pdb_directory, repair_pdb=repair_pdb) + self._validate_structure() + + def _validate_structure(self): + """Check that the structure is internally consistent.""" + L_seq = len(self.sequence) + L_dm = self.distance_matrix.shape[0] + if L_seq != L_dm: + raise ValueError( + f"Sequence length ({L_seq}) does not match distance matrix " + f"shape ({L_dm}x{L_dm}). The PDB may have missing residues. " + f"Try setting repair_pdb=True.") + + def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, + filtered_aligned_sequence, distance_matrix_method, + pdb_directory, repair_pdb): + try: #Check if file exists pdb_file=Path(pdb_file) @@ -91,7 +131,7 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s self.init_index_shift=0 if repair_pdb: - fixer=pdb.repair_pdb(pdb_file, chain, pdb_directory) + pdb.repair_pdb(pdb_file, chain, pdb_directory) self.pdb_file=str(pdb_directory/f"{self.pdbID}_cleaned.pdb") if ".pdb" in str(pdb_file) or repair_pdb==True: @@ -136,7 +176,7 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s self.init_index_shift=self.init_index-self.pdb_init_index self.fin_index_shift=self.fin_index-self.pdb_init_index+1 if repair_pdb: - fixer=pdb.repair_pdb(pdb_file, chain, pdb_directory) + pdb.repair_pdb(pdb_file, chain, pdb_directory) self.pdb_file=f"{pdb_directory}/{self.pdbID}_cleaned.pdb" self.select_gap_indices=[i for i in gap_indices if self.init_index<=i<=self.fin_index] self.fin_index_shift-=len(self.select_gap_indices) @@ -145,7 +185,7 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s self.init_index_shift=self.init_index self.fin_index_shift=self.fin_index+1 if repair_pdb: - fixer=pdb.repair_pdb(pdb_file, chain, pdb_directory) + pdb.repair_pdb(pdb_file, chain, pdb_directory) self.pdb_file=f"{pdb_directory}/{self.pdbID}_cleaned.pdb" self.chain="A" @@ -186,7 +226,7 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s @classmethod def full_pdb(cls,pdb_file: Union[Path,str], chain: Union[str,None]=None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, - distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb:bool = True): + distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None): warnings.warn("The class method 'full_pdb' is now depreciated. You can now simply call the Structure class to create a full pdb or spliced pdb object.") return cls(pdb_file=pdb_file, chain=chain, @@ -199,7 +239,7 @@ def full_pdb(cls,pdb_file: Union[Path,str], chain: Union[str,None]=None, aligned @classmethod def spliced_pdb(cls,pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_selection: str = None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, - distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb:bool = True): + distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None): warnings.warn("The class method 'spliced_pdb' is now depreciated. You can now simply call the Structure class to create a full pdb or spliced pdb object.") return cls(pdb_file=pdb_file, chain=chain, diff --git a/frustratometer/pdb/fix.py b/frustratometer/pdb/fix.py index a404a8b4..f3f6f592 100644 --- a/frustratometer/pdb/fix.py +++ b/frustratometer/pdb/fix.py @@ -1,58 +1,91 @@ from pathlib import Path +import logging +import multiprocessing import tempfile -import pdbfixer -PDBFile = pdbfixer.pdbfixer.app.PDBFile -PDBFixer = pdbfixer.PDBFixer +# Import guard: if pdbfixer is not installed, this ImportError +# propagates to __init__.py which provides a friendly fallback. +import pdbfixer # noqa: F401 -def repair_pdb(pdb_file: str, chain: str, pdb_directory: Path = None) -> PDBFixer: - """ - Repairs a pdb or cif file using pdbfixer. Note that a pdb file will be produced, regardless of input file format +logger = logging.getLogger(__name__) - Parameters - ---------- - pdb_file: str, - PDB file location. - chain: str, - Chain ID - pdb_directory: str, - PDB file location - Returns - ------- - fixer : object - Repaired PDB Object - """ - if pdb_directory is None: - pdb_directory = Path(tempfile.gettempdir()) - pdb_directory=Path(pdb_directory) - pdb_file=Path(pdb_file) - - pdbID=pdb_file.stem - fixer = PDBFixer(str(pdb_file)) - - chains = list(fixer.topology.chains()) - if chain!=None: - chains_to_remove = [i for i, x in enumerate(chains) if x.id not in chain] +def _repair_worker(pdb_file_str: str, chain: str, cleaned_path_str: str) -> None: + """Run PDBFixer in an isolated process to prevent OpenMM memory leaks.""" + import pdbfixer + + PDBFile = pdbfixer.pdbfixer.app.PDBFile + fixer = pdbfixer.PDBFixer(pdb_file_str) + + # Keep only the requested chain(s) + if chain is not None: + chains = list(fixer.topology.chains()) + chains_to_remove = [i for i, c in enumerate(chains) if c.id not in chain] fixer.removeChains(chains_to_remove) + # Fill in missing internal residues (skip terminal gaps) fixer.findMissingResidues() - #Filling in missing residues inside chain - chains = list(fixer.topology.chains()) - keys = fixer.missingResidues.keys() - for key in list(keys): - chain_tmp = chains[key[0]] - if key[1] == 0 or key[1] == len(list(chain_tmp.residues())): + for key in list(fixer.missingResidues): + chain_obj = list(fixer.topology.chains())[key[0]] + if key[1] == 0 or key[1] == len(list(chain_obj.residues())): del fixer.missingResidues[key] + fixer.findNonstandardResidues() fixer.replaceNonstandardResidues() fixer.removeHeterogens(keepWater=False) fixer.findMissingAtoms() try: fixer.addMissingAtoms() - except: - print("Unable to add missing atoms") - + except Exception: + pass fixer.addMissingHydrogens(7.0) - PDBFile.writeFile(fixer.topology, fixer.positions, open(f"{pdb_directory}/{pdbID}_cleaned.pdb", 'w')) - return fixer \ No newline at end of file + + with open(cleaned_path_str, 'w') as f: + PDBFile.writeFile(fixer.topology, fixer.positions, f) + + +def repair_pdb(pdb_file: str, chain: str, pdb_directory: Path = None) -> Path: + """ + Repair a PDB or CIF file using PDBFixer. + + Runs PDBFixer in a child process so that OpenMM's C-level memory + is fully reclaimed by the OS when the process exits. + + Fills in missing internal residues, replaces nonstandard residues, + removes heterogens, adds missing atoms and hydrogens, and writes + a cleaned PDB file. + + Parameters + ---------- + pdb_file : str or Path + PDB / mmCIF file location. + chain : str or None + Chain ID to keep. If None, all chains are kept. + pdb_directory : Path, optional + Directory for the cleaned output file. Defaults to the system temp dir. + + Returns + ------- + cleaned_path : Path + Path to the repaired PDB file (``/_cleaned.pdb``). + """ + if pdb_directory is None: + pdb_directory = Path(tempfile.gettempdir()) + pdb_directory = Path(pdb_directory) + pdb_file = Path(pdb_file) + + cleaned_path = pdb_directory / f"{pdb_file.stem}_cleaned.pdb" + + process = multiprocessing.Process( + target=_repair_worker, + args=(str(pdb_file), chain, str(cleaned_path)), + ) + process.start() + process.join() + + if process.exitcode != 0: + raise RuntimeError( + f"PDB repair failed for {pdb_file.name} (exit code {process.exitcode})" + ) + + return cleaned_path \ No newline at end of file diff --git a/tests/data/2GHY.pdb b/tests/data/2GHY.pdb new file mode 100644 index 00000000..4974d9ab --- /dev/null +++ b/tests/data/2GHY.pdb @@ -0,0 +1,1274 @@ +HEADER TRANSCRIPTION 28-MAR-06 2GHY +TITLE NOVEL CRYSTAL FORM OF THE COLE1 ROM PROTEIN +COMPND MOL_ID: 1; +COMPND 2 MOLECULE: REGULATORY PROTEIN ROP; +COMPND 3 CHAIN: A, B; +COMPND 4 SYNONYM: RNA ONE MODULATOR, ROM, COLE1 ROM PROTEIN; +COMPND 5 ENGINEERED: YES +SOURCE MOL_ID: 1; +SOURCE 2 ORGANISM_SCIENTIFIC: ESCHERICHIA COLI; +SOURCE 3 ORGANISM_TAXID: 562; +SOURCE 4 GENE: ROP; +SOURCE 5 EXPRESSION_SYSTEM: ESCHERICHIA COLI; +SOURCE 6 EXPRESSION_SYSTEM_TAXID: 562; +SOURCE 7 EXPRESSION_SYSTEM_VECTOR_TYPE: PLASMID; +SOURCE 8 EXPRESSION_SYSTEM_VECTOR: PMR103; +SOURCE 9 EXPRESSION_SYSTEM_PLASMID: P2R +KEYWDS RNA ONE MODULATOR PROTEIN, KISSING HAIRPINS, STRUCTURAL PACKING, HIV- +KEYWDS 2 1, TRANSCRIPTION +EXPDTA X-RAY DIFFRACTION +AUTHOR S.B.JANG,M.S.JEONG,R.J.CARTER,E.L.HOLBROOK,L.R.COMOLLI,S.R.HOLBROOK +REVDAT 3 25-OCT-23 2GHY 1 REMARK +REVDAT 2 24-FEB-09 2GHY 1 VERSN +REVDAT 1 30-MAY-06 2GHY 0 +JRNL AUTH S.B.JANG,M.S.JEONG,R.J.CARTER,E.L.HOLBROOK,L.R.COMOLLI, +JRNL AUTH 2 S.R.HOLBROOK +JRNL TITL NOVEL CRYSTAL FORM OF THE COLE1 ROM PROTEIN. +JRNL REF ACTA CRYSTALLOGR.,SECT.D V. 62 619 2006 +JRNL REFN ISSN 0907-4449 +JRNL PMID 16699189 +JRNL DOI 10.1107/S0907444906012388 +REMARK 2 +REMARK 2 RESOLUTION. 2.50 ANGSTROMS. +REMARK 3 +REMARK 3 REFINEMENT. +REMARK 3 PROGRAM : X-PLOR 3.851 +REMARK 3 AUTHORS : BRUNGER +REMARK 3 +REMARK 3 DATA USED IN REFINEMENT. +REMARK 3 RESOLUTION RANGE HIGH (ANGSTROMS) : 2.50 +REMARK 3 RESOLUTION RANGE LOW (ANGSTROMS) : 20.00 +REMARK 3 DATA CUTOFF (SIGMA(F)) : 1.000 +REMARK 3 DATA CUTOFF HIGH (ABS(F)) : NULL +REMARK 3 DATA CUTOFF LOW (ABS(F)) : NULL +REMARK 3 COMPLETENESS (WORKING+TEST) (%) : NULL +REMARK 3 NUMBER OF REFLECTIONS : 3487 +REMARK 3 +REMARK 3 FIT TO DATA USED IN REFINEMENT. +REMARK 3 CROSS-VALIDATION METHOD : NULL +REMARK 3 FREE R VALUE TEST SET SELECTION : RANDOM +REMARK 3 R VALUE (WORKING SET) : 0.179 +REMARK 3 FREE R VALUE : 0.263 +REMARK 3 FREE R VALUE TEST SET SIZE (%) : NULL +REMARK 3 FREE R VALUE TEST SET COUNT : 364 +REMARK 3 ESTIMATED ERROR OF FREE R VALUE : NULL +REMARK 3 +REMARK 3 FIT IN THE HIGHEST RESOLUTION BIN. +REMARK 3 TOTAL NUMBER OF BINS USED : NULL +REMARK 3 BIN RESOLUTION RANGE HIGH (A) : NULL +REMARK 3 BIN RESOLUTION RANGE LOW (A) : NULL +REMARK 3 BIN COMPLETENESS (WORKING+TEST) (%) : NULL +REMARK 3 REFLECTIONS IN BIN (WORKING SET) : NULL +REMARK 3 BIN R VALUE (WORKING SET) : NULL +REMARK 3 BIN FREE R VALUE : NULL +REMARK 3 BIN FREE R VALUE TEST SET SIZE (%) : NULL +REMARK 3 BIN FREE R VALUE TEST SET COUNT : NULL +REMARK 3 ESTIMATED ERROR OF BIN FREE R VALUE : NULL +REMARK 3 +REMARK 3 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT. +REMARK 3 PROTEIN ATOMS : 908 +REMARK 3 NUCLEIC ACID ATOMS : 0 +REMARK 3 HETEROGEN ATOMS : 0 +REMARK 3 SOLVENT ATOMS : 33 +REMARK 3 +REMARK 3 B VALUES. +REMARK 3 FROM WILSON PLOT (A**2) : NULL +REMARK 3 MEAN B VALUE (OVERALL, A**2) : NULL +REMARK 3 OVERALL ANISOTROPIC B VALUE. +REMARK 3 B11 (A**2) : NULL +REMARK 3 B22 (A**2) : NULL +REMARK 3 B33 (A**2) : NULL +REMARK 3 B12 (A**2) : NULL +REMARK 3 B13 (A**2) : NULL +REMARK 3 B23 (A**2) : NULL +REMARK 3 +REMARK 3 ESTIMATED COORDINATE ERROR. +REMARK 3 ESD FROM LUZZATI PLOT (A) : NULL +REMARK 3 ESD FROM SIGMAA (A) : NULL +REMARK 3 LOW RESOLUTION CUTOFF (A) : NULL +REMARK 3 +REMARK 3 CROSS-VALIDATED ESTIMATED COORDINATE ERROR. +REMARK 3 ESD FROM C-V LUZZATI PLOT (A) : NULL +REMARK 3 ESD FROM C-V SIGMAA (A) : NULL +REMARK 3 +REMARK 3 RMS DEVIATIONS FROM IDEAL VALUES. +REMARK 3 BOND LENGTHS (A) : 0.008 +REMARK 3 BOND ANGLES (DEGREES) : 2.151 +REMARK 3 DIHEDRAL ANGLES (DEGREES) : NULL +REMARK 3 IMPROPER ANGLES (DEGREES) : NULL +REMARK 3 +REMARK 3 ISOTROPIC THERMAL MODEL : NULL +REMARK 3 +REMARK 3 ISOTROPIC THERMAL FACTOR RESTRAINTS. RMS SIGMA +REMARK 3 MAIN-CHAIN BOND (A**2) : NULL ; NULL +REMARK 3 MAIN-CHAIN ANGLE (A**2) : NULL ; NULL +REMARK 3 SIDE-CHAIN BOND (A**2) : NULL ; NULL +REMARK 3 SIDE-CHAIN ANGLE (A**2) : NULL ; NULL +REMARK 3 +REMARK 3 NCS MODEL : NULL +REMARK 3 +REMARK 3 NCS RESTRAINTS. RMS SIGMA/WEIGHT +REMARK 3 GROUP 1 POSITIONAL (A) : NULL ; NULL +REMARK 3 GROUP 1 B-FACTOR (A**2) : NULL ; NULL +REMARK 3 +REMARK 3 PARAMETER FILE 1 : NULL +REMARK 3 TOPOLOGY FILE 1 : NULL +REMARK 3 +REMARK 3 OTHER REFINEMENT REMARKS: NULL +REMARK 4 +REMARK 4 2GHY COMPLIES WITH FORMAT V. 3.30, 13-JUL-11 +REMARK 100 +REMARK 100 THIS ENTRY HAS BEEN PROCESSED BY PDBJ ON 31-MAR-06. +REMARK 100 THE DEPOSITION ID IS D_1000037140. +REMARK 200 +REMARK 200 EXPERIMENTAL DETAILS +REMARK 200 EXPERIMENT TYPE : X-RAY DIFFRACTION +REMARK 200 DATE OF DATA COLLECTION : 01-AUG-97 +REMARK 200 TEMPERATURE (KELVIN) : 100 +REMARK 200 PH : 4.6 +REMARK 200 NUMBER OF CRYSTALS USED : 1 +REMARK 200 +REMARK 200 SYNCHROTRON (Y/N) : N +REMARK 200 RADIATION SOURCE : ROTATING ANODE +REMARK 200 BEAMLINE : NULL +REMARK 200 X-RAY GENERATOR MODEL : RIGAKU +REMARK 200 MONOCHROMATIC OR LAUE (M/L) : M +REMARK 200 WAVELENGTH OR RANGE (A) : 1.5418 +REMARK 200 MONOCHROMATOR : CU +REMARK 200 OPTICS : NULL +REMARK 200 +REMARK 200 DETECTOR TYPE : IMAGE PLATE +REMARK 200 DETECTOR MANUFACTURER : RIGAKU RAXIS II +REMARK 200 INTENSITY-INTEGRATION SOFTWARE : HKL-2000 +REMARK 200 DATA SCALING SOFTWARE : SCALEPACK +REMARK 200 +REMARK 200 NUMBER OF UNIQUE REFLECTIONS : 3487 +REMARK 200 RESOLUTION RANGE HIGH (A) : 2.500 +REMARK 200 RESOLUTION RANGE LOW (A) : 20.000 +REMARK 200 REJECTION CRITERIA (SIGMA(I)) : 1.000 +REMARK 200 +REMARK 200 OVERALL. +REMARK 200 COMPLETENESS FOR RANGE (%) : 97.5 +REMARK 200 DATA REDUNDANCY : NULL +REMARK 200 R MERGE (I) : NULL +REMARK 200 R SYM (I) : NULL +REMARK 200 FOR THE DATA SET : NULL +REMARK 200 +REMARK 200 IN THE HIGHEST RESOLUTION SHELL. +REMARK 200 HIGHEST RESOLUTION SHELL, RANGE HIGH (A) : 2.50 +REMARK 200 HIGHEST RESOLUTION SHELL, RANGE LOW (A) : 2.61 +REMARK 200 COMPLETENESS FOR SHELL (%) : 96.2 +REMARK 200 DATA REDUNDANCY IN SHELL : NULL +REMARK 200 R MERGE FOR SHELL (I) : NULL +REMARK 200 R SYM FOR SHELL (I) : NULL +REMARK 200 FOR SHELL : NULL +REMARK 200 +REMARK 200 DIFFRACTION PROTOCOL: SINGLE WAVELENGTH +REMARK 200 METHOD USED TO DETERMINE THE STRUCTURE: MOLECULAR REPLACEMENT +REMARK 200 SOFTWARE USED: AMORE +REMARK 200 STARTING MODEL: 1GTO +REMARK 200 +REMARK 200 REMARK: NULL +REMARK 280 +REMARK 280 CRYSTAL +REMARK 280 SOLVENT CONTENT, VS (%): 29.84 +REMARK 280 MATTHEWS COEFFICIENT, VM (ANGSTROMS**3/DA): 1.75 +REMARK 280 +REMARK 280 CRYSTALLIZATION CONDITIONS: 30% PEG MME 2000, 0.1M SODIUM ACETATE, +REMARK 280 PH4.6, AND 0.2M AMMONIUM SULFATE, VAPOR DIFFUSION, HANGING DROP, +REMARK 280 TEMPERATURE 295K +REMARK 290 +REMARK 290 CRYSTALLOGRAPHIC SYMMETRY +REMARK 290 SYMMETRY OPERATORS FOR SPACE GROUP: C 1 2 1 +REMARK 290 +REMARK 290 SYMOP SYMMETRY +REMARK 290 NNNMMM OPERATOR +REMARK 290 1555 X,Y,Z +REMARK 290 2555 -X,Y,-Z +REMARK 290 3555 X+1/2,Y+1/2,Z +REMARK 290 4555 -X+1/2,Y+1/2,-Z +REMARK 290 +REMARK 290 WHERE NNN -> OPERATOR NUMBER +REMARK 290 MMM -> TRANSLATION VECTOR +REMARK 290 +REMARK 290 CRYSTALLOGRAPHIC SYMMETRY TRANSFORMATIONS +REMARK 290 THE FOLLOWING TRANSFORMATIONS OPERATE ON THE ATOM/HETATM +REMARK 290 RECORDS IN THIS ENTRY TO PRODUCE CRYSTALLOGRAPHICALLY +REMARK 290 RELATED MOLECULES. +REMARK 290 SMTRY1 1 1.000000 0.000000 0.000000 0.00000 +REMARK 290 SMTRY2 1 0.000000 1.000000 0.000000 0.00000 +REMARK 290 SMTRY3 1 0.000000 0.000000 1.000000 0.00000 +REMARK 290 SMTRY1 2 -1.000000 0.000000 0.000000 0.00000 +REMARK 290 SMTRY2 2 0.000000 1.000000 0.000000 0.00000 +REMARK 290 SMTRY3 2 0.000000 0.000000 -1.000000 0.00000 +REMARK 290 SMTRY1 3 1.000000 0.000000 0.000000 48.88500 +REMARK 290 SMTRY2 3 0.000000 1.000000 0.000000 19.55500 +REMARK 290 SMTRY3 3 0.000000 0.000000 1.000000 0.00000 +REMARK 290 SMTRY1 4 -1.000000 0.000000 0.000000 48.88500 +REMARK 290 SMTRY2 4 0.000000 1.000000 0.000000 19.55500 +REMARK 290 SMTRY3 4 0.000000 0.000000 -1.000000 0.00000 +REMARK 290 +REMARK 290 REMARK: NULL +REMARK 300 +REMARK 300 BIOMOLECULE: 1 +REMARK 300 SEE REMARK 350 FOR THE AUTHOR PROVIDED AND/OR PROGRAM +REMARK 300 GENERATED ASSEMBLY INFORMATION FOR THE STRUCTURE IN +REMARK 300 THIS ENTRY. THE REMARK MAY ALSO PROVIDE INFORMATION ON +REMARK 300 BURIED SURFACE AREA. +REMARK 350 +REMARK 350 COORDINATES FOR A COMPLETE MULTIMER REPRESENTING THE KNOWN +REMARK 350 BIOLOGICALLY SIGNIFICANT OLIGOMERIZATION STATE OF THE +REMARK 350 MOLECULE CAN BE GENERATED BY APPLYING BIOMT TRANSFORMATIONS +REMARK 350 GIVEN BELOW. BOTH NON-CRYSTALLOGRAPHIC AND +REMARK 350 CRYSTALLOGRAPHIC OPERATIONS ARE GIVEN. +REMARK 350 +REMARK 350 BIOMOLECULE: 1 +REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: DIMERIC +REMARK 350 SOFTWARE DETERMINED QUATERNARY STRUCTURE: DIMERIC +REMARK 350 SOFTWARE USED: PISA +REMARK 350 TOTAL BURIED SURFACE AREA: 2540 ANGSTROM**2 +REMARK 350 SURFACE AREA OF THE COMPLEX: 6140 ANGSTROM**2 +REMARK 350 CHANGE IN SOLVENT FREE ENERGY: -28.0 KCAL/MOL +REMARK 350 APPLY THE FOLLOWING TO CHAINS: A, B +REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000 +REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000 +REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000 +REMARK 465 +REMARK 465 MISSING RESIDUES +REMARK 465 THE FOLLOWING RESIDUES WERE NOT LOCATED IN THE +REMARK 465 EXPERIMENT. (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN +REMARK 465 IDENTIFIER; SSSEQ=SEQUENCE NUMBER; I=INSERTION CODE.) +REMARK 465 +REMARK 465 M RES C SSSEQI +REMARK 465 ASP A 58 +REMARK 465 ASP A 59 +REMARK 465 GLY A 60 +REMARK 465 GLU A 61 +REMARK 465 ASN A 62 +REMARK 465 LEU A 63 +REMARK 465 ASP B 58 +REMARK 465 ASP B 59 +REMARK 465 GLY B 60 +REMARK 465 GLU B 61 +REMARK 465 ASN B 62 +REMARK 465 LEU B 63 +REMARK 470 +REMARK 470 MISSING ATOM +REMARK 470 THE FOLLOWING RESIDUES HAVE MISSING ATOMS (M=MODEL NUMBER; +REMARK 470 RES=RESIDUE NAME; C=CHAIN IDENTIFIER; SSEQ=SEQUENCE NUMBER; +REMARK 470 I=INSERTION CODE): +REMARK 470 M RES CSSEQI ATOMS +REMARK 470 ASP A 30 CB CG OD1 OD2 +REMARK 470 ASP B 30 CB CG OD1 OD2 +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: COVALENT BOND LENGTHS +REMARK 500 +REMARK 500 THE STEREOCHEMICAL PARAMETERS OF THE FOLLOWING RESIDUES +REMARK 500 HAVE VALUES WHICH DEVIATE FROM EXPECTED VALUES BY MORE +REMARK 500 THAN 6*RMSD (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN +REMARK 500 IDENTIFIER; SSEQ=SEQUENCE NUMBER; I=INSERTION CODE). +REMARK 500 +REMARK 500 STANDARD TABLE: +REMARK 500 FORMAT: (10X,I3,1X,2(A3,1X,A1,I4,A1,1X,A4,3X),1X,F6.3) +REMARK 500 +REMARK 500 EXPECTED VALUES PROTEIN: ENGH AND HUBER, 1999 +REMARK 500 EXPECTED VALUES NUCLEIC ACID: CLOWNEY ET AL 1996 +REMARK 500 +REMARK 500 M RES CSSEQI ATM1 RES CSSEQI ATM2 DEVIATION +REMARK 500 HIS A 44 NE2 HIS A 44 CD2 -0.068 +REMARK 500 HIS B 42 NE2 HIS B 42 CD2 -0.073 +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: TORSION ANGLES +REMARK 500 +REMARK 500 TORSION ANGLES OUTSIDE THE EXPECTED RAMACHANDRAN REGIONS: +REMARK 500 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER; +REMARK 500 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE). +REMARK 500 +REMARK 500 STANDARD TABLE: +REMARK 500 FORMAT:(10X,I3,1X,A3,1X,A1,I4,A1,4X,F7.2,3X,F7.2) +REMARK 500 +REMARK 500 EXPECTED VALUES: GJ KLEYWEGT AND TA JONES (1996). PHI/PSI- +REMARK 500 CHOLOGY: RAMACHANDRAN REVISITED. STRUCTURE 4, 1395 - 1400 +REMARK 500 +REMARK 500 M RES CSSEQI PSI PHI +REMARK 500 THR A 2 -23.36 65.91 +REMARK 500 LYS A 3 -45.55 75.76 +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 900 +REMARK 900 RELATED ENTRIES +REMARK 900 RELATED ID: 1ROP RELATED DB: PDB +REMARK 900 STRUCTURE OF THE COLE1 ROP PROTEIN +DBREF 2GHY A 1 63 UNP P03051 ROP_ECOLI 1 63 +DBREF 2GHY B 1 63 UNP P03051 ROP_ECOLI 1 63 +SEQRES 1 A 63 MET THR LYS GLN GLU LYS THR ALA LEU ASN MET ALA ARG +SEQRES 2 A 63 PHE ILE ARG SER GLN THR LEU THR LEU LEU GLU LYS LEU +SEQRES 3 A 63 ASN GLU LEU ASP ALA ASP GLU GLN ALA ASP ILE CYS GLU +SEQRES 4 A 63 SER LEU HIS ASP HIS ALA ASP GLU LEU TYR ARG SER CYS +SEQRES 5 A 63 LEU ALA ARG PHE GLY ASP ASP GLY GLU ASN LEU +SEQRES 1 B 63 MET THR LYS GLN GLU LYS THR ALA LEU ASN MET ALA ARG +SEQRES 2 B 63 PHE ILE ARG SER GLN THR LEU THR LEU LEU GLU LYS LEU +SEQRES 3 B 63 ASN GLU LEU ASP ALA ASP GLU GLN ALA ASP ILE CYS GLU +SEQRES 4 B 63 SER LEU HIS ASP HIS ALA ASP GLU LEU TYR ARG SER CYS +SEQRES 5 B 63 LEU ALA ARG PHE GLY ASP ASP GLY GLU ASN LEU +FORMUL 3 HOH *33(H2 O) +HELIX 1 1 LYS A 3 LEU A 29 1 27 +HELIX 2 2 ALA A 31 GLY A 57 1 27 +HELIX 3 3 MET B 1 ASP B 30 1 30 +HELIX 4 4 ALA B 31 GLY B 57 1 27 +CRYST1 97.770 39.110 26.700 90.00 96.16 90.00 C 1 2 1 8 +ORIGX1 1.000000 0.000000 0.000000 0.00000 +ORIGX2 0.000000 1.000000 0.000000 0.00000 +ORIGX3 0.000000 0.000000 1.000000 0.00000 +SCALE1 0.010228 0.000000 0.001104 0.00000 +SCALE2 0.000000 0.025569 0.000000 0.00000 +SCALE3 0.000000 0.000000 0.037671 0.00000 +ATOM 1 N MET A 1 40.454 -24.342 8.740 1.00 36.54 N +ATOM 2 CA MET A 1 40.103 -23.327 9.720 1.00 38.15 C +ATOM 3 C MET A 1 38.803 -23.709 10.399 1.00 37.14 C +ATOM 4 O MET A 1 37.691 -23.534 9.886 1.00 37.48 O +ATOM 5 CB MET A 1 39.947 -21.962 9.049 1.00 40.81 C +ATOM 6 CG MET A 1 41.261 -21.398 8.531 1.00 44.80 C +ATOM 7 SD MET A 1 41.040 -19.879 7.574 1.00 49.63 S +ATOM 8 CE MET A 1 40.626 -20.605 6.014 1.00 49.87 C +ATOM 9 N THR A 2 39.028 -24.326 11.568 1.00 35.38 N +ATOM 10 CA THR A 2 38.012 -24.852 12.477 1.00 31.27 C +ATOM 11 C THR A 2 37.197 -26.027 11.932 1.00 30.21 C +ATOM 12 O THR A 2 36.731 -26.824 12.752 1.00 31.33 O +ATOM 13 CB THR A 2 37.073 -23.678 12.915 1.00 30.10 C +ATOM 14 OG1 THR A 2 37.962 -22.744 13.510 1.00 31.34 O +ATOM 15 CG2 THR A 2 36.001 -23.991 13.948 1.00 27.95 C +ATOM 16 N LYS A 3 37.082 -26.211 10.592 1.00 25.60 N +ATOM 17 CA LYS A 3 36.262 -27.199 9.867 1.00 23.24 C +ATOM 18 C LYS A 3 34.795 -26.796 9.871 1.00 19.45 C +ATOM 19 O LYS A 3 34.113 -26.905 8.859 1.00 17.96 O +ATOM 20 CB LYS A 3 36.292 -28.617 10.451 1.00 22.71 C +ATOM 21 CG LYS A 3 37.643 -29.277 10.648 1.00 21.87 C +ATOM 22 CD LYS A 3 37.508 -30.472 11.583 1.00 18.76 C +ATOM 23 CE LYS A 3 36.626 -31.526 10.943 1.00 20.49 C +ATOM 24 NZ LYS A 3 36.270 -32.550 11.896 1.00 20.85 N +ATOM 25 N GLN A 4 34.312 -26.390 11.050 1.00 17.56 N +ATOM 26 CA GLN A 4 32.978 -25.882 11.273 1.00 17.44 C +ATOM 27 C GLN A 4 32.757 -24.556 10.550 1.00 16.09 C +ATOM 28 O GLN A 4 31.670 -24.339 10.012 1.00 18.32 O +ATOM 29 CB GLN A 4 32.740 -25.680 12.770 1.00 21.28 C +ATOM 30 CG GLN A 4 32.659 -26.906 13.672 1.00 28.43 C +ATOM 31 CD GLN A 4 33.991 -27.544 14.044 1.00 34.57 C +ATOM 32 OE1 GLN A 4 34.298 -28.667 13.646 1.00 39.23 O +ATOM 33 NE2 GLN A 4 34.822 -26.868 14.836 1.00 36.51 N +ATOM 34 N GLU A 5 33.754 -23.655 10.526 1.00 10.27 N +ATOM 35 CA GLU A 5 33.664 -22.403 9.792 1.00 9.34 C +ATOM 36 C GLU A 5 33.498 -22.650 8.306 1.00 11.26 C +ATOM 37 O GLU A 5 32.802 -21.907 7.606 1.00 10.01 O +ATOM 38 CB GLU A 5 34.909 -21.564 9.941 1.00 11.80 C +ATOM 39 CG GLU A 5 35.145 -21.018 11.335 1.00 17.51 C +ATOM 40 CD GLU A 5 36.475 -20.297 11.535 1.00 17.56 C +ATOM 41 OE1 GLU A 5 37.468 -20.660 10.907 1.00 20.15 O +ATOM 42 OE2 GLU A 5 36.523 -19.377 12.348 1.00 20.28 O +ATOM 43 N LYS A 6 34.181 -23.697 7.819 1.00 12.01 N +ATOM 44 CA LYS A 6 34.082 -24.074 6.420 1.00 12.27 C +ATOM 45 C LYS A 6 32.747 -24.734 6.080 1.00 8.95 C +ATOM 46 O LYS A 6 32.256 -24.559 4.967 1.00 10.01 O +ATOM 47 CB LYS A 6 35.252 -24.992 6.088 1.00 19.89 C +ATOM 48 CG LYS A 6 36.596 -24.241 6.075 1.00 25.87 C +ATOM 49 CD LYS A 6 37.764 -25.151 5.679 1.00 28.56 C +ATOM 50 CE LYS A 6 38.071 -26.210 6.742 1.00 31.31 C +ATOM 51 NZ LYS A 6 39.087 -27.142 6.286 1.00 30.75 N +ATOM 52 N THR A 7 32.132 -25.452 7.033 1.00 4.03 N +ATOM 53 CA THR A 7 30.799 -26.033 6.891 1.00 3.34 C +ATOM 54 C THR A 7 29.775 -24.914 6.761 1.00 4.26 C +ATOM 55 O THR A 7 28.869 -24.983 5.928 1.00 2.00 O +ATOM 56 CB THR A 7 30.490 -26.939 8.126 1.00 4.82 C +ATOM 57 OG1 THR A 7 31.384 -28.028 7.986 1.00 2.00 O +ATOM 58 CG2 THR A 7 29.073 -27.496 8.229 1.00 2.00 C +ATOM 59 N ALA A 8 29.959 -23.853 7.562 1.00 4.33 N +ATOM 60 CA ALA A 8 29.105 -22.677 7.509 1.00 4.84 C +ATOM 61 C ALA A 8 29.173 -21.983 6.156 1.00 6.82 C +ATOM 62 O ALA A 8 28.139 -21.712 5.542 1.00 10.14 O +ATOM 63 CB ALA A 8 29.515 -21.668 8.569 1.00 2.09 C +ATOM 64 N LEU A 9 30.402 -21.741 5.674 1.00 8.83 N +ATOM 65 CA LEU A 9 30.637 -21.119 4.378 1.00 7.85 C +ATOM 66 C LEU A 9 30.085 -21.915 3.190 1.00 8.06 C +ATOM 67 O LEU A 9 29.462 -21.331 2.303 1.00 8.02 O +ATOM 68 CB LEU A 9 32.130 -20.907 4.199 1.00 4.19 C +ATOM 69 CG LEU A 9 32.585 -20.251 2.912 1.00 4.00 C +ATOM 70 CD1 LEU A 9 31.922 -18.899 2.790 1.00 4.01 C +ATOM 71 CD2 LEU A 9 34.093 -20.121 2.901 1.00 3.93 C +ATOM 72 N ASN A 10 30.269 -23.239 3.174 1.00 8.57 N +ATOM 73 CA ASN A 10 29.769 -24.077 2.098 1.00 11.69 C +ATOM 74 C ASN A 10 28.260 -24.088 1.999 1.00 12.04 C +ATOM 75 O ASN A 10 27.718 -24.119 0.892 1.00 15.39 O +ATOM 76 CB ASN A 10 30.240 -25.516 2.269 1.00 15.07 C +ATOM 77 CG ASN A 10 31.700 -25.746 1.913 1.00 15.42 C +ATOM 78 OD1 ASN A 10 32.369 -24.907 1.310 1.00 18.07 O +ATOM 79 ND2 ASN A 10 32.228 -26.915 2.266 1.00 18.59 N +ATOM 80 N MET A 11 27.602 -24.025 3.167 1.00 11.79 N +ATOM 81 CA MET A 11 26.154 -23.994 3.243 1.00 7.41 C +ATOM 82 C MET A 11 25.599 -22.636 2.846 1.00 7.68 C +ATOM 83 O MET A 11 24.552 -22.584 2.196 1.00 9.41 O +ATOM 84 CB MET A 11 25.701 -24.318 4.640 1.00 5.61 C +ATOM 85 CG MET A 11 24.232 -24.665 4.619 1.00 2.91 C +ATOM 86 SD MET A 11 23.673 -25.243 6.224 1.00 6.60 S +ATOM 87 CE MET A 11 24.255 -26.914 6.166 1.00 2.00 C +ATOM 88 N ALA A 12 26.279 -21.538 3.213 1.00 6.53 N +ATOM 89 CA ALA A 12 25.881 -20.204 2.773 1.00 4.85 C +ATOM 90 C ALA A 12 25.998 -20.121 1.251 1.00 4.15 C +ATOM 91 O ALA A 12 25.156 -19.523 0.584 1.00 6.35 O +ATOM 92 CB ALA A 12 26.785 -19.148 3.410 1.00 2.05 C +ATOM 93 N ARG A 13 27.007 -20.795 0.682 1.00 4.66 N +ATOM 94 CA ARG A 13 27.209 -20.840 -0.759 1.00 5.93 C +ATOM 95 C ARG A 13 26.120 -21.663 -1.430 1.00 6.78 C +ATOM 96 O ARG A 13 25.602 -21.273 -2.473 1.00 5.52 O +ATOM 97 CB ARG A 13 28.553 -21.459 -1.085 1.00 5.48 C +ATOM 98 CG ARG A 13 28.915 -21.390 -2.564 1.00 2.00 C +ATOM 99 CD ARG A 13 30.260 -22.047 -2.815 1.00 4.15 C +ATOM 100 NE ARG A 13 31.319 -21.241 -2.229 1.00 10.87 N +ATOM 101 CZ ARG A 13 32.173 -21.704 -1.315 1.00 12.25 C +ATOM 102 NH1 ARG A 13 32.110 -22.962 -0.874 1.00 13.89 N +ATOM 103 NH2 ARG A 13 33.096 -20.875 -0.823 1.00 13.25 N +ATOM 104 N PHE A 14 25.755 -22.793 -0.820 1.00 6.67 N +ATOM 105 CA PHE A 14 24.707 -23.651 -1.342 1.00 5.51 C +ATOM 106 C PHE A 14 23.398 -22.890 -1.455 1.00 3.99 C +ATOM 107 O PHE A 14 22.776 -22.937 -2.512 1.00 7.10 O +ATOM 108 CB PHE A 14 24.510 -24.855 -0.423 1.00 3.36 C +ATOM 109 CG PHE A 14 23.513 -25.885 -0.932 1.00 2.00 C +ATOM 110 CD1 PHE A 14 23.641 -26.425 -2.223 1.00 3.30 C +ATOM 111 CD2 PHE A 14 22.496 -26.319 -0.084 1.00 2.00 C +ATOM 112 CE1 PHE A 14 22.746 -27.408 -2.656 1.00 3.58 C +ATOM 113 CE2 PHE A 14 21.604 -27.300 -0.524 1.00 2.30 C +ATOM 114 CZ PHE A 14 21.725 -27.847 -1.806 1.00 4.14 C +ATOM 115 N ILE A 15 23.004 -22.154 -0.410 1.00 2.58 N +ATOM 116 CA ILE A 15 21.743 -21.417 -0.411 1.00 6.39 C +ATOM 117 C ILE A 15 21.786 -20.362 -1.507 1.00 8.10 C +ATOM 118 O ILE A 15 20.800 -20.174 -2.220 1.00 11.79 O +ATOM 119 CB ILE A 15 21.514 -20.776 0.991 1.00 7.69 C +ATOM 120 CG1 ILE A 15 21.306 -21.893 2.015 1.00 6.45 C +ATOM 121 CG2 ILE A 15 20.293 -19.854 0.989 1.00 3.90 C +ATOM 122 CD1 ILE A 15 21.314 -21.416 3.482 1.00 10.78 C +ATOM 123 N ARG A 16 22.957 -19.742 -1.696 1.00 6.76 N +ATOM 124 CA ARG A 16 23.167 -18.790 -2.770 1.00 6.61 C +ATOM 125 C ARG A 16 22.852 -19.463 -4.108 1.00 6.50 C +ATOM 126 O ARG A 16 21.994 -18.972 -4.838 1.00 5.44 O +ATOM 127 CB ARG A 16 24.605 -18.331 -2.689 1.00 9.31 C +ATOM 128 CG ARG A 16 24.799 -16.849 -2.853 1.00 12.15 C +ATOM 129 CD ARG A 16 25.507 -16.429 -4.125 1.00 13.83 C +ATOM 130 NE ARG A 16 26.896 -16.860 -4.163 1.00 16.09 N +ATOM 131 CZ ARG A 16 27.770 -16.326 -5.024 1.00 18.71 C +ATOM 132 NH1 ARG A 16 27.424 -15.367 -5.878 1.00 20.87 N +ATOM 133 NH2 ARG A 16 29.004 -16.810 -5.097 1.00 17.96 N +ATOM 134 N SER A 17 23.428 -20.656 -4.350 1.00 6.89 N +ATOM 135 CA SER A 17 23.239 -21.454 -5.567 1.00 7.03 C +ATOM 136 C SER A 17 21.811 -21.824 -5.871 1.00 8.43 C +ATOM 137 O SER A 17 21.352 -21.690 -7.002 1.00 10.54 O +ATOM 138 CB SER A 17 23.952 -22.797 -5.534 1.00 4.21 C +ATOM 139 OG SER A 17 25.355 -22.692 -5.471 1.00 14.55 O +ATOM 140 N GLN A 18 21.137 -22.296 -4.818 1.00 9.83 N +ATOM 141 CA GLN A 18 19.797 -22.838 -4.920 1.00 10.00 C +ATOM 142 C GLN A 18 18.654 -21.857 -5.003 1.00 7.64 C +ATOM 143 O GLN A 18 17.627 -22.185 -5.588 1.00 5.51 O +ATOM 144 CB GLN A 18 19.559 -23.771 -3.745 1.00 12.50 C +ATOM 145 CG GLN A 18 20.543 -24.923 -3.753 1.00 11.70 C +ATOM 146 CD GLN A 18 20.600 -25.715 -5.049 1.00 14.04 C +ATOM 147 OE1 GLN A 18 19.604 -26.246 -5.540 1.00 16.12 O +ATOM 148 NE2 GLN A 18 21.796 -25.805 -5.621 1.00 13.23 N +ATOM 149 N THR A 19 18.788 -20.674 -4.400 1.00 6.51 N +ATOM 150 CA THR A 19 17.757 -19.646 -4.507 1.00 6.82 C +ATOM 151 C THR A 19 17.767 -19.071 -5.922 1.00 7.51 C +ATOM 152 O THR A 19 16.727 -18.665 -6.442 1.00 8.42 O +ATOM 153 CB THR A 19 18.002 -18.538 -3.451 1.00 2.06 C +ATOM 154 OG1 THR A 19 19.365 -18.170 -3.526 1.00 8.82 O +ATOM 155 CG2 THR A 19 17.741 -19.004 -2.039 1.00 2.00 C +ATOM 156 N LEU A 20 18.958 -19.106 -6.549 1.00 9.04 N +ATOM 157 CA LEU A 20 19.175 -18.708 -7.936 1.00 7.99 C +ATOM 158 C LEU A 20 18.611 -19.750 -8.893 1.00 7.88 C +ATOM 159 O LEU A 20 17.921 -19.367 -9.835 1.00 8.40 O +ATOM 160 CB LEU A 20 20.674 -18.540 -8.195 1.00 8.13 C +ATOM 161 CG LEU A 20 21.191 -18.144 -9.574 1.00 8.57 C +ATOM 162 CD1 LEU A 20 20.656 -16.773 -9.988 1.00 8.04 C +ATOM 163 CD2 LEU A 20 22.706 -18.128 -9.526 1.00 8.47 C +ATOM 164 N THR A 21 18.880 -21.055 -8.680 1.00 6.96 N +ATOM 165 CA THR A 21 18.348 -22.114 -9.539 1.00 7.98 C +ATOM 166 C THR A 21 16.827 -22.110 -9.452 1.00 6.08 C +ATOM 167 O THR A 21 16.138 -22.169 -10.468 1.00 6.68 O +ATOM 168 CB THR A 21 18.874 -23.530 -9.125 1.00 8.14 C +ATOM 169 OG1 THR A 21 20.281 -23.534 -9.307 1.00 9.52 O +ATOM 170 CG2 THR A 21 18.309 -24.652 -9.987 1.00 8.35 C +ATOM 171 N LEU A 22 16.313 -21.984 -8.228 1.00 5.69 N +ATOM 172 CA LEU A 22 14.891 -21.910 -7.988 1.00 5.72 C +ATOM 173 C LEU A 22 14.318 -20.655 -8.632 1.00 7.35 C +ATOM 174 O LEU A 22 13.248 -20.738 -9.228 1.00 9.60 O +ATOM 175 CB LEU A 22 14.656 -21.908 -6.493 1.00 3.73 C +ATOM 176 CG LEU A 22 13.236 -21.787 -5.966 1.00 6.42 C +ATOM 177 CD1 LEU A 22 12.362 -22.911 -6.509 1.00 6.73 C +ATOM 178 CD2 LEU A 22 13.299 -21.778 -4.450 1.00 5.15 C +ATOM 179 N LEU A 23 15.019 -19.513 -8.584 1.00 7.64 N +ATOM 180 CA LEU A 23 14.551 -18.291 -9.221 1.00 8.58 C +ATOM 181 C LEU A 23 14.342 -18.483 -10.716 1.00 10.02 C +ATOM 182 O LEU A 23 13.290 -18.117 -11.244 1.00 12.75 O +ATOM 183 CB LEU A 23 15.558 -17.167 -8.997 1.00 6.60 C +ATOM 184 CG LEU A 23 15.403 -15.853 -9.758 1.00 5.08 C +ATOM 185 CD1 LEU A 23 14.037 -15.240 -9.508 1.00 3.54 C +ATOM 186 CD2 LEU A 23 16.532 -14.937 -9.335 1.00 2.08 C +ATOM 187 N GLU A 24 15.320 -19.095 -11.392 1.00 10.08 N +ATOM 188 CA GLU A 24 15.210 -19.335 -12.822 1.00 9.32 C +ATOM 189 C GLU A 24 14.132 -20.352 -13.143 1.00 9.28 C +ATOM 190 O GLU A 24 13.410 -20.174 -14.122 1.00 5.53 O +ATOM 191 CB GLU A 24 16.539 -19.821 -13.376 1.00 11.23 C +ATOM 192 CG GLU A 24 17.726 -18.889 -13.088 1.00 13.18 C +ATOM 193 CD GLU A 24 17.505 -17.407 -13.390 1.00 12.96 C +ATOM 194 OE1 GLU A 24 17.512 -16.625 -12.435 1.00 9.58 O +ATOM 195 OE2 GLU A 24 17.328 -17.048 -14.559 1.00 8.32 O +ATOM 196 N LYS A 25 13.958 -21.369 -12.284 1.00 8.33 N +ATOM 197 CA LYS A 25 12.906 -22.354 -12.475 1.00 13.17 C +ATOM 198 C LYS A 25 11.503 -21.809 -12.252 1.00 13.02 C +ATOM 199 O LYS A 25 10.551 -22.274 -12.875 1.00 14.16 O +ATOM 200 CB LYS A 25 13.103 -23.536 -11.548 1.00 14.95 C +ATOM 201 CG LYS A 25 14.239 -24.414 -12.022 1.00 18.83 C +ATOM 202 CD LYS A 25 14.238 -25.669 -11.180 1.00 21.29 C +ATOM 203 CE LYS A 25 15.413 -26.557 -11.539 1.00 22.67 C +ATOM 204 NZ LYS A 25 15.269 -27.095 -12.875 1.00 28.77 N +ATOM 205 N LEU A 26 11.371 -20.808 -11.378 1.00 12.86 N +ATOM 206 CA LEU A 26 10.100 -20.146 -11.136 1.00 12.40 C +ATOM 207 C LEU A 26 9.781 -19.253 -12.313 1.00 10.61 C +ATOM 208 O LEU A 26 8.614 -19.108 -12.656 1.00 15.45 O +ATOM 209 CB LEU A 26 10.160 -19.310 -9.847 1.00 10.54 C +ATOM 210 CG LEU A 26 10.197 -20.111 -8.535 1.00 10.71 C +ATOM 211 CD1 LEU A 26 10.512 -19.164 -7.393 1.00 6.36 C +ATOM 212 CD2 LEU A 26 8.876 -20.852 -8.321 1.00 2.92 C +ATOM 213 N ASN A 27 10.790 -18.653 -12.958 1.00 11.63 N +ATOM 214 CA ASN A 27 10.554 -17.898 -14.176 1.00 8.68 C +ATOM 215 C ASN A 27 10.190 -18.828 -15.317 1.00 9.08 C +ATOM 216 O ASN A 27 9.320 -18.478 -16.114 1.00 13.97 O +ATOM 217 CB ASN A 27 11.780 -17.093 -14.542 1.00 10.09 C +ATOM 218 CG ASN A 27 11.998 -15.914 -13.597 1.00 11.51 C +ATOM 219 OD1 ASN A 27 13.133 -15.587 -13.243 1.00 8.66 O +ATOM 220 ND2 ASN A 27 10.925 -15.235 -13.174 1.00 6.10 N +ATOM 221 N GLU A 28 10.766 -20.041 -15.375 1.00 6.92 N +ATOM 222 CA GLU A 28 10.372 -21.041 -16.370 1.00 7.46 C +ATOM 223 C GLU A 28 8.932 -21.548 -16.220 1.00 8.41 C +ATOM 224 O GLU A 28 8.297 -21.954 -17.193 1.00 8.68 O +ATOM 225 CB GLU A 28 11.292 -22.231 -16.299 1.00 5.91 C +ATOM 226 CG GLU A 28 12.674 -21.943 -16.852 1.00 7.64 C +ATOM 227 CD GLU A 28 13.603 -23.139 -16.926 1.00 9.47 C +ATOM 228 OE1 GLU A 28 13.195 -24.247 -16.581 1.00 15.16 O +ATOM 229 OE2 GLU A 28 14.744 -22.966 -17.350 1.00 7.81 O +ATOM 230 N LEU A 29 8.420 -21.522 -14.984 1.00 9.99 N +ATOM 231 CA LEU A 29 7.055 -21.884 -14.656 1.00 10.25 C +ATOM 232 C LEU A 29 6.091 -20.700 -14.746 1.00 12.28 C +ATOM 233 O LEU A 29 4.913 -20.814 -14.390 1.00 11.12 O +ATOM 234 CB LEU A 29 7.006 -22.443 -13.248 1.00 12.16 C +ATOM 235 CG LEU A 29 7.574 -23.830 -13.000 1.00 14.74 C +ATOM 236 CD1 LEU A 29 7.642 -24.062 -11.503 1.00 13.71 C +ATOM 237 CD2 LEU A 29 6.723 -24.881 -13.707 1.00 14.10 C +ATOM 238 N ASP A 30 6.592 -19.533 -15.185 1.00 12.56 N +ATOM 239 CA ASP A 30 5.801 -18.315 -15.319 1.00 14.59 C +ATOM 240 C ASP A 30 5.087 -17.909 -14.041 1.00 14.55 C +ATOM 241 O ASP A 30 3.999 -17.346 -14.083 1.00 16.66 O +ATOM 242 N ALA A 31 5.705 -18.240 -12.906 1.00 14.72 N +ATOM 243 CA ALA A 31 5.170 -17.946 -11.595 1.00 14.06 C +ATOM 244 C ALA A 31 5.732 -16.630 -11.066 1.00 14.98 C +ATOM 245 O ALA A 31 6.601 -16.608 -10.201 1.00 17.43 O +ATOM 246 CB ALA A 31 5.531 -19.114 -10.684 1.00 11.31 C +ATOM 247 N ASP A 32 5.223 -15.518 -11.607 1.00 17.94 N +ATOM 248 CA ASP A 32 5.647 -14.147 -11.303 1.00 21.27 C +ATOM 249 C ASP A 32 5.734 -13.680 -9.859 1.00 22.31 C +ATOM 250 O ASP A 32 6.730 -13.089 -9.436 1.00 21.35 O +ATOM 251 CB ASP A 32 4.741 -13.140 -12.014 1.00 24.32 C +ATOM 252 CG ASP A 32 4.821 -13.222 -13.525 1.00 29.01 C +ATOM 253 OD1 ASP A 32 5.577 -12.442 -14.104 1.00 30.64 O +ATOM 254 OD2 ASP A 32 4.129 -14.060 -14.109 1.00 29.42 O +ATOM 255 N GLU A 33 4.666 -13.919 -9.099 1.00 24.21 N +ATOM 256 CA GLU A 33 4.606 -13.511 -7.705 1.00 23.75 C +ATOM 257 C GLU A 33 5.630 -14.250 -6.836 1.00 18.66 C +ATOM 258 O GLU A 33 6.152 -13.673 -5.880 1.00 19.40 O +ATOM 259 CB GLU A 33 3.176 -13.755 -7.237 1.00 27.22 C +ATOM 260 CG GLU A 33 2.824 -13.060 -5.936 1.00 36.07 C +ATOM 261 CD GLU A 33 2.371 -14.004 -4.830 1.00 41.49 C +ATOM 262 OE1 GLU A 33 3.179 -14.817 -4.387 1.00 45.81 O +ATOM 263 OE2 GLU A 33 1.216 -13.923 -4.407 1.00 44.39 O +ATOM 264 N GLN A 34 5.937 -15.510 -7.198 1.00 14.18 N +ATOM 265 CA GLN A 34 6.915 -16.353 -6.507 1.00 11.56 C +ATOM 266 C GLN A 34 8.332 -16.028 -6.957 1.00 9.13 C +ATOM 267 O GLN A 34 9.265 -16.036 -6.162 1.00 9.31 O +ATOM 268 CB GLN A 34 6.669 -17.836 -6.781 1.00 8.02 C +ATOM 269 CG GLN A 34 5.450 -18.496 -6.169 1.00 7.46 C +ATOM 270 CD GLN A 34 4.100 -17.956 -6.617 1.00 13.21 C +ATOM 271 OE1 GLN A 34 3.878 -17.605 -7.777 1.00 16.35 O +ATOM 272 NE2 GLN A 34 3.141 -17.860 -5.703 1.00 14.27 N +ATOM 273 N ALA A 35 8.501 -15.721 -8.244 1.00 9.54 N +ATOM 274 CA ALA A 35 9.775 -15.300 -8.799 1.00 10.73 C +ATOM 275 C ALA A 35 10.234 -13.964 -8.218 1.00 13.49 C +ATOM 276 O ALA A 35 11.437 -13.724 -8.077 1.00 17.12 O +ATOM 277 CB ALA A 35 9.656 -15.141 -10.286 1.00 9.17 C +ATOM 278 N ASP A 36 9.277 -13.095 -7.861 1.00 13.03 N +ATOM 279 CA ASP A 36 9.585 -11.820 -7.237 1.00 13.49 C +ATOM 280 C ASP A 36 10.132 -11.994 -5.830 1.00 13.70 C +ATOM 281 O ASP A 36 11.119 -11.336 -5.481 1.00 16.85 O +ATOM 282 CB ASP A 36 8.348 -10.927 -7.154 1.00 13.86 C +ATOM 283 CG ASP A 36 7.836 -10.322 -8.460 1.00 14.67 C +ATOM 284 OD1 ASP A 36 6.842 -9.601 -8.428 1.00 18.75 O +ATOM 285 OD2 ASP A 36 8.401 -10.567 -9.517 1.00 18.31 O +ATOM 286 N ILE A 37 9.531 -12.883 -5.021 1.00 9.77 N +ATOM 287 CA ILE A 37 10.013 -13.114 -3.658 1.00 6.84 C +ATOM 288 C ILE A 37 11.354 -13.840 -3.732 1.00 4.62 C +ATOM 289 O ILE A 37 12.294 -13.434 -3.058 1.00 2.00 O +ATOM 290 CB ILE A 37 8.986 -13.959 -2.828 1.00 2.72 C +ATOM 291 CG1 ILE A 37 7.637 -13.271 -2.771 1.00 4.42 C +ATOM 292 CG2 ILE A 37 9.468 -14.102 -1.401 1.00 2.00 C +ATOM 293 CD1 ILE A 37 6.522 -14.170 -2.206 1.00 5.25 C +ATOM 294 N CYS A 38 11.489 -14.864 -4.581 1.00 3.65 N +ATOM 295 CA CYS A 38 12.734 -15.597 -4.709 1.00 5.46 C +ATOM 296 C CYS A 38 13.884 -14.736 -5.183 1.00 5.44 C +ATOM 297 O CYS A 38 15.002 -14.996 -4.762 1.00 7.29 O +ATOM 298 CB CYS A 38 12.588 -16.747 -5.677 1.00 3.00 C +ATOM 299 SG CYS A 38 13.902 -17.960 -5.403 1.00 4.41 S +ATOM 300 N GLU A 39 13.678 -13.712 -6.026 1.00 8.92 N +ATOM 301 CA GLU A 39 14.769 -12.828 -6.433 1.00 9.61 C +ATOM 302 C GLU A 39 15.276 -12.057 -5.223 1.00 8.40 C +ATOM 303 O GLU A 39 16.489 -12.002 -5.013 1.00 11.04 O +ATOM 304 CB GLU A 39 14.306 -11.840 -7.520 1.00 13.15 C +ATOM 305 CG GLU A 39 15.447 -10.936 -8.031 1.00 19.68 C +ATOM 306 CD GLU A 39 15.690 -10.873 -9.540 1.00 20.22 C +ATOM 307 OE1 GLU A 39 16.028 -9.808 -10.056 1.00 21.33 O +ATOM 308 OE2 GLU A 39 15.568 -11.891 -10.208 1.00 22.46 O +ATOM 309 N SER A 40 14.368 -11.507 -4.400 1.00 5.76 N +ATOM 310 CA SER A 40 14.738 -10.818 -3.170 1.00 5.71 C +ATOM 311 C SER A 40 15.441 -11.762 -2.199 1.00 5.02 C +ATOM 312 O SER A 40 16.445 -11.385 -1.608 1.00 4.07 O +ATOM 313 CB SER A 40 13.498 -10.247 -2.512 1.00 7.28 C +ATOM 314 OG SER A 40 13.805 -9.694 -1.239 1.00 13.30 O +ATOM 315 N LEU A 41 14.963 -13.006 -2.071 1.00 5.74 N +ATOM 316 CA LEU A 41 15.596 -14.014 -1.239 1.00 7.77 C +ATOM 317 C LEU A 41 17.011 -14.256 -1.748 1.00 5.49 C +ATOM 318 O LEU A 41 17.940 -14.024 -0.979 1.00 10.91 O +ATOM 319 CB LEU A 41 14.779 -15.323 -1.270 1.00 7.81 C +ATOM 320 CG LEU A 41 15.390 -16.568 -0.614 1.00 10.32 C +ATOM 321 CD1 LEU A 41 15.598 -16.324 0.861 1.00 10.47 C +ATOM 322 CD2 LEU A 41 14.478 -17.754 -0.788 1.00 7.09 C +ATOM 323 N HIS A 42 17.207 -14.659 -3.009 1.00 3.38 N +ATOM 324 CA HIS A 42 18.525 -14.844 -3.605 1.00 4.20 C +ATOM 325 C HIS A 42 19.479 -13.678 -3.352 1.00 4.28 C +ATOM 326 O HIS A 42 20.652 -13.924 -3.078 1.00 5.64 O +ATOM 327 CB HIS A 42 18.400 -15.063 -5.131 1.00 4.68 C +ATOM 328 CG HIS A 42 19.759 -15.042 -5.827 1.00 6.55 C +ATOM 329 ND1 HIS A 42 20.323 -14.018 -6.462 1.00 8.05 N +ATOM 330 CD2 HIS A 42 20.666 -16.074 -5.832 1.00 8.96 C +ATOM 331 CE1 HIS A 42 21.525 -14.385 -6.842 1.00 9.78 C +ATOM 332 NE2 HIS A 42 21.722 -15.625 -6.459 1.00 11.45 N +ATOM 333 N ASP A 43 18.995 -12.429 -3.432 1.00 4.95 N +ATOM 334 CA ASP A 43 19.812 -11.251 -3.163 1.00 6.62 C +ATOM 335 C ASP A 43 20.434 -11.281 -1.774 1.00 7.19 C +ATOM 336 O ASP A 43 21.621 -10.984 -1.638 1.00 7.95 O +ATOM 337 CB ASP A 43 18.991 -9.962 -3.266 1.00 3.57 C +ATOM 338 CG ASP A 43 18.493 -9.582 -4.648 1.00 7.25 C +ATOM 339 OD1 ASP A 43 17.658 -8.683 -4.711 1.00 3.30 O +ATOM 340 OD2 ASP A 43 18.926 -10.165 -5.649 1.00 7.81 O +ATOM 341 N HIS A 44 19.629 -11.663 -0.766 1.00 4.55 N +ATOM 342 CA HIS A 44 20.081 -11.770 0.614 1.00 6.58 C +ATOM 343 C HIS A 44 20.935 -13.022 0.856 1.00 3.74 C +ATOM 344 O HIS A 44 21.786 -13.054 1.740 1.00 2.00 O +ATOM 345 CB HIS A 44 18.824 -11.727 1.515 1.00 7.43 C +ATOM 346 CG HIS A 44 18.156 -10.350 1.507 1.00 12.51 C +ATOM 347 ND1 HIS A 44 17.105 -9.929 0.810 1.00 12.36 N +ATOM 348 CD2 HIS A 44 18.615 -9.266 2.222 1.00 12.37 C +ATOM 349 CE1 HIS A 44 16.919 -8.656 1.059 1.00 13.65 C +ATOM 350 NE2 HIS A 44 17.836 -8.265 1.913 1.00 12.69 N +ATOM 351 N ALA A 45 20.738 -14.073 0.053 1.00 3.79 N +ATOM 352 CA ALA A 45 21.552 -15.279 0.102 1.00 3.34 C +ATOM 353 C ALA A 45 22.959 -14.952 -0.378 1.00 4.42 C +ATOM 354 O ALA A 45 23.967 -15.409 0.165 1.00 2.00 O +ATOM 355 CB ALA A 45 20.966 -16.338 -0.808 1.00 2.00 C +ATOM 356 N ASP A 46 22.979 -14.085 -1.398 1.00 4.50 N +ATOM 357 CA ASP A 46 24.189 -13.580 -2.014 1.00 8.45 C +ATOM 358 C ASP A 46 24.917 -12.674 -1.036 1.00 8.93 C +ATOM 359 O ASP A 46 26.127 -12.801 -0.852 1.00 10.63 O +ATOM 360 CB ASP A 46 23.763 -12.864 -3.304 1.00 11.78 C +ATOM 361 CG ASP A 46 24.812 -12.063 -4.067 1.00 14.55 C +ATOM 362 OD1 ASP A 46 26.007 -12.356 -3.995 1.00 7.99 O +ATOM 363 OD2 ASP A 46 24.401 -11.124 -4.751 1.00 19.68 O +ATOM 364 N GLU A 47 24.167 -11.799 -0.366 1.00 7.01 N +ATOM 365 CA GLU A 47 24.731 -10.949 0.655 1.00 7.15 C +ATOM 366 C GLU A 47 25.313 -11.743 1.829 1.00 7.63 C +ATOM 367 O GLU A 47 26.421 -11.441 2.279 1.00 6.76 O +ATOM 368 CB GLU A 47 23.657 -10.031 1.143 1.00 8.51 C +ATOM 369 CG GLU A 47 23.241 -9.024 0.091 1.00 6.82 C +ATOM 370 CD GLU A 47 21.909 -8.341 0.351 1.00 5.15 C +ATOM 371 OE1 GLU A 47 21.476 -8.315 1.500 1.00 4.14 O +ATOM 372 OE2 GLU A 47 21.305 -7.849 -0.607 1.00 2.53 O +ATOM 373 N LEU A 48 24.608 -12.789 2.301 1.00 6.71 N +ATOM 374 CA LEU A 48 25.088 -13.622 3.407 1.00 8.81 C +ATOM 375 C LEU A 48 26.359 -14.380 3.071 1.00 5.84 C +ATOM 376 O LEU A 48 27.231 -14.525 3.926 1.00 8.14 O +ATOM 377 CB LEU A 48 24.042 -14.656 3.832 1.00 6.61 C +ATOM 378 CG LEU A 48 24.444 -15.650 4.919 1.00 4.96 C +ATOM 379 CD1 LEU A 48 24.828 -14.927 6.209 1.00 2.51 C +ATOM 380 CD2 LEU A 48 23.292 -16.597 5.136 1.00 4.49 C +ATOM 381 N TYR A 49 26.454 -14.855 1.830 1.00 5.04 N +ATOM 382 CA TYR A 49 27.643 -15.530 1.375 1.00 4.33 C +ATOM 383 C TYR A 49 28.838 -14.591 1.322 1.00 5.70 C +ATOM 384 O TYR A 49 29.919 -15.012 1.739 1.00 8.50 O +ATOM 385 CB TYR A 49 27.383 -16.120 0.008 1.00 8.38 C +ATOM 386 CG TYR A 49 28.632 -16.676 -0.663 1.00 9.80 C +ATOM 387 CD1 TYR A 49 29.225 -17.855 -0.201 1.00 8.99 C +ATOM 388 CD2 TYR A 49 29.184 -15.980 -1.743 1.00 9.27 C +ATOM 389 CE1 TYR A 49 30.376 -18.333 -0.828 1.00 10.51 C +ATOM 390 CE2 TYR A 49 30.333 -16.459 -2.362 1.00 9.85 C +ATOM 391 CZ TYR A 49 30.917 -17.632 -1.905 1.00 8.84 C +ATOM 392 OH TYR A 49 32.035 -18.113 -2.547 1.00 13.59 O +ATOM 393 N ARG A 50 28.688 -13.348 0.837 1.00 5.18 N +ATOM 394 CA ARG A 50 29.809 -12.404 0.734 1.00 5.98 C +ATOM 395 C ARG A 50 30.431 -12.129 2.103 1.00 8.54 C +ATOM 396 O ARG A 50 31.655 -12.144 2.272 1.00 11.10 O +ATOM 397 CB ARG A 50 29.371 -11.053 0.167 1.00 7.76 C +ATOM 398 CG ARG A 50 28.643 -10.981 -1.163 1.00 7.08 C +ATOM 399 CD ARG A 50 29.510 -11.472 -2.292 1.00 11.24 C +ATOM 400 NE ARG A 50 28.798 -11.383 -3.549 1.00 8.75 N +ATOM 401 CZ ARG A 50 29.414 -11.472 -4.730 1.00 7.82 C +ATOM 402 NH1 ARG A 50 30.727 -11.641 -4.842 1.00 6.16 N +ATOM 403 NH2 ARG A 50 28.677 -11.421 -5.833 1.00 9.92 N +ATOM 404 N SER A 51 29.531 -11.888 3.067 1.00 5.73 N +ATOM 405 CA SER A 51 29.841 -11.682 4.478 1.00 6.68 C +ATOM 406 C SER A 51 30.552 -12.896 5.108 1.00 7.03 C +ATOM 407 O SER A 51 31.615 -12.754 5.717 1.00 7.35 O +ATOM 408 CB SER A 51 28.501 -11.370 5.161 1.00 7.54 C +ATOM 409 OG SER A 51 28.570 -10.999 6.525 1.00 7.29 O +ATOM 410 N CYS A 52 29.996 -14.109 4.939 1.00 5.97 N +ATOM 411 CA CYS A 52 30.602 -15.337 5.454 1.00 7.38 C +ATOM 412 C CYS A 52 31.893 -15.706 4.735 1.00 7.18 C +ATOM 413 O CYS A 52 32.748 -16.352 5.335 1.00 6.37 O +ATOM 414 CB CYS A 52 29.685 -16.552 5.314 1.00 6.98 C +ATOM 415 SG CYS A 52 28.209 -16.593 6.354 1.00 4.39 S +ATOM 416 N LEU A 53 32.060 -15.323 3.458 1.00 5.80 N +ATOM 417 CA LEU A 53 33.287 -15.619 2.733 1.00 5.46 C +ATOM 418 C LEU A 53 34.443 -14.793 3.287 1.00 5.93 C +ATOM 419 O LEU A 53 35.536 -15.314 3.520 1.00 8.64 O +ATOM 420 CB LEU A 53 33.109 -15.308 1.259 1.00 3.27 C +ATOM 421 CG LEU A 53 34.261 -15.638 0.312 1.00 3.80 C +ATOM 422 CD1 LEU A 53 34.487 -17.143 0.272 1.00 2.97 C +ATOM 423 CD2 LEU A 53 33.934 -15.094 -1.067 1.00 2.00 C +ATOM 424 N ALA A 54 34.172 -13.503 3.528 1.00 5.93 N +ATOM 425 CA ALA A 54 35.134 -12.584 4.104 1.00 8.39 C +ATOM 426 C ALA A 54 35.603 -13.036 5.486 1.00 8.97 C +ATOM 427 O ALA A 54 36.800 -12.997 5.762 1.00 7.37 O +ATOM 428 CB ALA A 54 34.512 -11.194 4.232 1.00 7.73 C +ATOM 429 N ARG A 55 34.668 -13.535 6.315 1.00 11.26 N +ATOM 430 CA ARG A 55 34.955 -13.996 7.664 1.00 10.38 C +ATOM 431 C ARG A 55 35.515 -15.406 7.791 1.00 10.37 C +ATOM 432 O ARG A 55 36.317 -15.644 8.692 1.00 10.81 O +ATOM 433 CB ARG A 55 33.690 -13.922 8.537 1.00 11.16 C +ATOM 434 CG ARG A 55 34.009 -14.133 10.025 1.00 11.38 C +ATOM 435 CD ARG A 55 32.822 -14.086 10.960 1.00 11.30 C +ATOM 436 NE ARG A 55 33.268 -14.352 12.318 1.00 12.08 N +ATOM 437 CZ ARG A 55 32.926 -13.591 13.358 1.00 11.70 C +ATOM 438 NH1 ARG A 55 32.146 -12.525 13.225 1.00 15.87 N +ATOM 439 NH2 ARG A 55 33.366 -13.912 14.569 1.00 11.22 N +ATOM 440 N PHE A 56 35.153 -16.359 6.932 1.00 10.22 N +ATOM 441 CA PHE A 56 35.539 -17.751 7.133 1.00 13.63 C +ATOM 442 C PHE A 56 36.499 -18.368 6.139 1.00 18.34 C +ATOM 443 O PHE A 56 37.227 -19.307 6.476 1.00 21.22 O +ATOM 444 CB PHE A 56 34.292 -18.623 7.164 1.00 9.89 C +ATOM 445 CG PHE A 56 33.368 -18.321 8.326 1.00 9.75 C +ATOM 446 CD1 PHE A 56 33.895 -18.112 9.617 1.00 5.87 C +ATOM 447 CD2 PHE A 56 31.988 -18.281 8.097 1.00 5.29 C +ATOM 448 CE1 PHE A 56 33.027 -17.867 10.680 1.00 4.70 C +ATOM 449 CE2 PHE A 56 31.131 -18.034 9.172 1.00 2.56 C +ATOM 450 CZ PHE A 56 31.648 -17.829 10.457 1.00 5.51 C +ATOM 451 N GLY A 57 36.450 -17.867 4.899 1.00 21.04 N +ATOM 452 CA GLY A 57 37.285 -18.363 3.814 1.00 23.14 C +ATOM 453 C GLY A 57 38.714 -17.848 3.860 1.00 23.24 C +ATOM 454 O GLY A 57 39.595 -18.539 3.356 1.00 24.36 O +TER 455 GLY A 57 +ATOM 456 N MET B 1 4.362 -27.907 -14.987 1.00 36.87 N +ATOM 457 CA MET B 1 3.580 -29.107 -14.722 1.00 36.98 C +ATOM 458 C MET B 1 3.972 -29.741 -13.392 1.00 33.89 C +ATOM 459 O MET B 1 4.981 -29.347 -12.815 1.00 31.53 O +ATOM 460 CB MET B 1 3.791 -30.078 -15.873 1.00 41.06 C +ATOM 461 CG MET B 1 3.281 -29.545 -17.215 1.00 43.90 C +ATOM 462 SD MET B 1 4.003 -30.428 -18.621 1.00 47.30 S +ATOM 463 CE MET B 1 5.685 -29.901 -18.418 1.00 44.99 C +ATOM 464 N THR B 2 3.201 -30.723 -12.896 1.00 32.78 N +ATOM 465 CA THR B 2 3.403 -31.341 -11.583 1.00 32.38 C +ATOM 466 C THR B 2 4.822 -31.698 -11.169 1.00 31.85 C +ATOM 467 O THR B 2 5.189 -31.208 -10.105 1.00 35.02 O +ATOM 468 CB THR B 2 2.556 -32.633 -11.420 1.00 30.16 C +ATOM 469 OG1 THR B 2 1.213 -32.276 -11.678 1.00 30.49 O +ATOM 470 CG2 THR B 2 2.590 -33.216 -10.009 1.00 26.64 C +ATOM 471 N LYS B 3 5.647 -32.477 -11.896 1.00 29.79 N +ATOM 472 CA LYS B 3 6.986 -32.795 -11.399 1.00 29.36 C +ATOM 473 C LYS B 3 7.862 -31.572 -11.187 1.00 28.64 C +ATOM 474 O LYS B 3 8.375 -31.456 -10.076 1.00 28.73 O +ATOM 475 CB LYS B 3 7.728 -33.778 -12.335 1.00 33.42 C +ATOM 476 CG LYS B 3 7.737 -33.549 -13.851 1.00 38.71 C +ATOM 477 CD LYS B 3 8.497 -34.646 -14.598 1.00 39.80 C +ATOM 478 CE LYS B 3 8.236 -34.552 -16.101 1.00 40.58 C +ATOM 479 NZ LYS B 3 9.031 -35.526 -16.826 1.00 38.33 N +ATOM 480 N GLN B 4 7.971 -30.612 -12.131 1.00 25.51 N +ATOM 481 CA GLN B 4 8.800 -29.420 -11.935 1.00 22.36 C +ATOM 482 C GLN B 4 8.210 -28.365 -11.009 1.00 20.58 C +ATOM 483 O GLN B 4 8.936 -27.532 -10.460 1.00 18.63 O +ATOM 484 CB GLN B 4 9.156 -28.722 -13.276 1.00 23.08 C +ATOM 485 CG GLN B 4 8.214 -28.703 -14.473 1.00 25.06 C +ATOM 486 CD GLN B 4 8.190 -30.027 -15.226 1.00 27.09 C +ATOM 487 OE1 GLN B 4 9.204 -30.503 -15.733 1.00 26.46 O +ATOM 488 NE2 GLN B 4 7.036 -30.684 -15.295 1.00 28.98 N +ATOM 489 N GLU B 5 6.894 -28.408 -10.810 1.00 19.99 N +ATOM 490 CA GLU B 5 6.227 -27.541 -9.851 1.00 24.60 C +ATOM 491 C GLU B 5 6.386 -28.076 -8.445 1.00 24.78 C +ATOM 492 O GLU B 5 6.434 -27.320 -7.474 1.00 27.10 O +ATOM 493 CB GLU B 5 4.756 -27.451 -10.109 1.00 26.68 C +ATOM 494 CG GLU B 5 4.453 -26.607 -11.317 1.00 29.35 C +ATOM 495 CD GLU B 5 3.001 -26.619 -11.771 1.00 31.78 C +ATOM 496 OE1 GLU B 5 2.116 -27.104 -11.057 1.00 31.00 O +ATOM 497 OE2 GLU B 5 2.774 -26.132 -12.875 1.00 34.20 O +ATOM 498 N LYS B 6 6.472 -29.405 -8.354 1.00 24.54 N +ATOM 499 CA LYS B 6 6.634 -30.069 -7.080 1.00 23.81 C +ATOM 500 C LYS B 6 8.057 -29.867 -6.615 1.00 18.69 C +ATOM 501 O LYS B 6 8.269 -29.491 -5.471 1.00 20.46 O +ATOM 502 CB LYS B 6 6.346 -31.560 -7.213 1.00 26.05 C +ATOM 503 CG LYS B 6 5.938 -32.188 -5.883 1.00 33.50 C +ATOM 504 CD LYS B 6 4.640 -31.570 -5.313 1.00 38.11 C +ATOM 505 CE LYS B 6 3.392 -31.765 -6.189 1.00 38.95 C +ATOM 506 NZ LYS B 6 3.127 -33.173 -6.447 1.00 37.50 N +ATOM 507 N THR B 7 9.018 -30.048 -7.522 1.00 14.64 N +ATOM 508 CA THR B 7 10.422 -29.888 -7.199 1.00 11.64 C +ATOM 509 C THR B 7 10.802 -28.439 -6.940 1.00 8.00 C +ATOM 510 O THR B 7 11.787 -28.194 -6.258 1.00 6.38 O +ATOM 511 CB THR B 7 11.284 -30.465 -8.336 1.00 14.10 C +ATOM 512 OG1 THR B 7 11.037 -29.704 -9.497 1.00 17.31 O +ATOM 513 CG2 THR B 7 10.958 -31.925 -8.608 1.00 15.34 C +ATOM 514 N ALA B 8 10.047 -27.464 -7.465 1.00 7.92 N +ATOM 515 CA ALA B 8 10.276 -26.057 -7.155 1.00 7.49 C +ATOM 516 C ALA B 8 9.832 -25.796 -5.714 1.00 7.36 C +ATOM 517 O ALA B 8 10.516 -25.110 -4.950 1.00 6.33 O +ATOM 518 CB ALA B 8 9.470 -25.157 -8.081 1.00 3.39 C +ATOM 519 N LEU B 9 8.702 -26.399 -5.317 1.00 7.76 N +ATOM 520 CA LEU B 9 8.200 -26.313 -3.950 1.00 7.23 C +ATOM 521 C LEU B 9 9.153 -27.010 -2.992 1.00 7.15 C +ATOM 522 O LEU B 9 9.378 -26.511 -1.891 1.00 14.37 O +ATOM 523 CB LEU B 9 6.821 -26.963 -3.865 1.00 8.11 C +ATOM 524 CG LEU B 9 6.174 -27.196 -2.502 1.00 9.39 C +ATOM 525 CD1 LEU B 9 5.880 -25.873 -1.843 1.00 8.39 C +ATOM 526 CD2 LEU B 9 4.908 -28.011 -2.675 1.00 9.26 C +ATOM 527 N ASN B 10 9.747 -28.140 -3.388 1.00 5.41 N +ATOM 528 CA ASN B 10 10.678 -28.874 -2.541 1.00 5.46 C +ATOM 529 C ASN B 10 12.016 -28.166 -2.364 1.00 4.42 C +ATOM 530 O ASN B 10 12.670 -28.353 -1.344 1.00 5.63 O +ATOM 531 CB ASN B 10 10.938 -30.256 -3.117 1.00 6.56 C +ATOM 532 CG ASN B 10 9.783 -31.247 -3.191 1.00 7.59 C +ATOM 533 OD1 ASN B 10 9.935 -32.282 -3.842 1.00 10.33 O +ATOM 534 ND2 ASN B 10 8.625 -31.023 -2.567 1.00 6.64 N +ATOM 535 N MET B 11 12.433 -27.365 -3.353 1.00 3.32 N +ATOM 536 CA MET B 11 13.621 -26.549 -3.255 1.00 3.06 C +ATOM 537 C MET B 11 13.380 -25.397 -2.305 1.00 2.79 C +ATOM 538 O MET B 11 14.223 -25.128 -1.457 1.00 8.49 O +ATOM 539 CB MET B 11 14.021 -25.992 -4.611 1.00 6.69 C +ATOM 540 CG MET B 11 14.886 -26.959 -5.404 1.00 9.65 C +ATOM 541 SD MET B 11 15.654 -26.228 -6.873 1.00 12.56 S +ATOM 542 CE MET B 11 14.304 -26.681 -7.910 1.00 17.57 C +ATOM 543 N ALA B 12 12.225 -24.739 -2.378 1.00 2.99 N +ATOM 544 CA ALA B 12 11.857 -23.673 -1.445 1.00 5.46 C +ATOM 545 C ALA B 12 11.740 -24.119 0.024 1.00 7.45 C +ATOM 546 O ALA B 12 11.926 -23.330 0.955 1.00 9.53 O +ATOM 547 CB ALA B 12 10.522 -23.081 -1.876 1.00 4.66 C +ATOM 548 N ARG B 13 11.445 -25.414 0.215 1.00 8.46 N +ATOM 549 CA ARG B 13 11.309 -26.055 1.519 1.00 9.05 C +ATOM 550 C ARG B 13 12.648 -26.355 2.164 1.00 6.37 C +ATOM 551 O ARG B 13 12.831 -26.066 3.351 1.00 5.04 O +ATOM 552 CB ARG B 13 10.553 -27.368 1.385 1.00 13.32 C +ATOM 553 CG ARG B 13 9.974 -27.911 2.688 1.00 14.70 C +ATOM 554 CD ARG B 13 9.241 -29.210 2.399 1.00 22.20 C +ATOM 555 NE ARG B 13 8.275 -29.054 1.316 1.00 26.22 N +ATOM 556 CZ ARG B 13 7.887 -30.070 0.546 1.00 25.71 C +ATOM 557 NH1 ARG B 13 8.361 -31.303 0.723 1.00 28.50 N +ATOM 558 NH2 ARG B 13 7.009 -29.843 -0.424 1.00 26.20 N +ATOM 559 N PHE B 14 13.576 -26.945 1.386 1.00 3.89 N +ATOM 560 CA PHE B 14 14.885 -27.257 1.925 1.00 4.96 C +ATOM 561 C PHE B 14 15.696 -25.980 2.085 1.00 3.47 C +ATOM 562 O PHE B 14 16.539 -25.955 2.972 1.00 4.49 O +ATOM 563 CB PHE B 14 15.648 -28.304 1.028 1.00 3.35 C +ATOM 564 CG PHE B 14 16.394 -27.953 -0.270 1.00 7.22 C +ATOM 565 CD1 PHE B 14 17.464 -27.042 -0.305 1.00 8.10 C +ATOM 566 CD2 PHE B 14 16.035 -28.609 -1.450 1.00 6.89 C +ATOM 567 CE1 PHE B 14 18.153 -26.800 -1.499 1.00 7.02 C +ATOM 568 CE2 PHE B 14 16.732 -28.364 -2.639 1.00 7.88 C +ATOM 569 CZ PHE B 14 17.790 -27.460 -2.668 1.00 5.66 C +ATOM 570 N ILE B 15 15.479 -24.914 1.293 1.00 2.05 N +ATOM 571 CA ILE B 15 16.167 -23.648 1.506 1.00 2.00 C +ATOM 572 C ILE B 15 15.707 -23.009 2.817 1.00 3.44 C +ATOM 573 O ILE B 15 16.528 -22.470 3.566 1.00 4.42 O +ATOM 574 CB ILE B 15 15.903 -22.705 0.312 1.00 2.95 C +ATOM 575 CG1 ILE B 15 16.567 -23.279 -0.940 1.00 2.00 C +ATOM 576 CG2 ILE B 15 16.478 -21.306 0.602 1.00 2.00 C +ATOM 577 CD1 ILE B 15 16.215 -22.547 -2.246 1.00 2.00 C +ATOM 578 N ARG B 16 14.404 -23.085 3.124 1.00 2.48 N +ATOM 579 CA ARG B 16 13.885 -22.610 4.402 1.00 4.23 C +ATOM 580 C ARG B 16 14.527 -23.401 5.547 1.00 4.83 C +ATOM 581 O ARG B 16 14.935 -22.797 6.544 1.00 5.20 O +ATOM 582 CB ARG B 16 12.377 -22.781 4.397 1.00 3.06 C +ATOM 583 CG ARG B 16 11.570 -22.296 5.597 1.00 2.00 C +ATOM 584 CD ARG B 16 10.447 -23.320 5.562 1.00 3.98 C +ATOM 585 NE ARG B 16 9.237 -22.967 6.272 1.00 6.20 N +ATOM 586 CZ ARG B 16 8.270 -23.870 6.472 1.00 6.91 C +ATOM 587 NH1 ARG B 16 8.376 -25.125 6.045 1.00 5.67 N +ATOM 588 NH2 ARG B 16 7.138 -23.501 7.061 1.00 8.29 N +ATOM 589 N SER B 17 14.665 -24.739 5.404 1.00 5.16 N +ATOM 590 CA SER B 17 15.368 -25.563 6.390 1.00 5.76 C +ATOM 591 C SER B 17 16.835 -25.168 6.560 1.00 6.56 C +ATOM 592 O SER B 17 17.308 -24.976 7.674 1.00 8.23 O +ATOM 593 CB SER B 17 15.353 -27.040 6.007 1.00 5.94 C +ATOM 594 OG SER B 17 14.125 -27.710 6.224 1.00 12.73 O +ATOM 595 N GLN B 18 17.547 -24.975 5.443 1.00 7.37 N +ATOM 596 CA GLN B 18 18.968 -24.682 5.429 1.00 3.59 C +ATOM 597 C GLN B 18 19.317 -23.355 6.063 1.00 3.40 C +ATOM 598 O GLN B 18 20.431 -23.191 6.560 1.00 2.83 O +ATOM 599 CB GLN B 18 19.494 -24.691 3.988 1.00 3.33 C +ATOM 600 CG GLN B 18 19.607 -26.052 3.289 1.00 2.00 C +ATOM 601 CD GLN B 18 20.607 -26.981 3.941 1.00 2.00 C +ATOM 602 OE1 GLN B 18 20.271 -27.760 4.827 1.00 3.31 O +ATOM 603 NE2 GLN B 18 21.871 -26.909 3.537 1.00 2.00 N +ATOM 604 N THR B 19 18.380 -22.404 6.035 1.00 4.20 N +ATOM 605 CA THR B 19 18.609 -21.115 6.665 1.00 8.74 C +ATOM 606 C THR B 19 18.455 -21.218 8.175 1.00 10.98 C +ATOM 607 O THR B 19 19.094 -20.451 8.897 1.00 15.87 O +ATOM 608 CB THR B 19 17.648 -20.028 6.120 1.00 8.25 C +ATOM 609 OG1 THR B 19 16.315 -20.515 6.184 1.00 10.06 O +ATOM 610 CG2 THR B 19 18.039 -19.624 4.712 1.00 2.00 C +ATOM 611 N LEU B 20 17.650 -22.171 8.675 1.00 11.10 N +ATOM 612 CA LEU B 20 17.582 -22.419 10.105 1.00 9.42 C +ATOM 613 C LEU B 20 18.875 -23.098 10.560 1.00 10.63 C +ATOM 614 O LEU B 20 19.506 -22.667 11.529 1.00 7.93 O +ATOM 615 CB LEU B 20 16.413 -23.333 10.457 1.00 7.66 C +ATOM 616 CG LEU B 20 15.478 -22.909 11.592 1.00 7.91 C +ATOM 617 CD1 LEU B 20 14.530 -24.049 11.894 1.00 6.70 C +ATOM 618 CD2 LEU B 20 16.253 -22.571 12.850 1.00 7.28 C +ATOM 619 N THR B 21 19.280 -24.145 9.815 1.00 11.30 N +ATOM 620 CA THR B 21 20.471 -24.944 10.112 1.00 8.62 C +ATOM 621 C THR B 21 21.750 -24.131 10.008 1.00 7.12 C +ATOM 622 O THR B 21 22.654 -24.336 10.818 1.00 7.05 O +ATOM 623 CB THR B 21 20.532 -26.170 9.159 1.00 7.01 C +ATOM 624 OG1 THR B 21 19.281 -26.830 9.298 1.00 8.57 O +ATOM 625 CG2 THR B 21 21.593 -27.199 9.516 1.00 7.68 C +ATOM 626 N LEU B 22 21.832 -23.187 9.059 1.00 4.85 N +ATOM 627 CA LEU B 22 22.995 -22.323 8.973 1.00 5.45 C +ATOM 628 C LEU B 22 22.918 -21.219 10.030 1.00 8.24 C +ATOM 629 O LEU B 22 23.964 -20.741 10.467 1.00 8.23 O +ATOM 630 CB LEU B 22 23.107 -21.677 7.594 1.00 2.69 C +ATOM 631 CG LEU B 22 24.324 -20.768 7.348 1.00 2.22 C +ATOM 632 CD1 LEU B 22 25.612 -21.560 7.366 1.00 2.00 C +ATOM 633 CD2 LEU B 22 24.193 -20.118 6.001 1.00 7.42 C +ATOM 634 N LEU B 23 21.731 -20.777 10.481 1.00 10.43 N +ATOM 635 CA LEU B 23 21.662 -19.784 11.549 1.00 12.74 C +ATOM 636 C LEU B 23 22.142 -20.410 12.856 1.00 15.53 C +ATOM 637 O LEU B 23 22.874 -19.761 13.601 1.00 18.36 O +ATOM 638 CB LEU B 23 20.227 -19.275 11.684 1.00 10.55 C +ATOM 639 CG LEU B 23 19.783 -18.397 12.850 1.00 8.01 C +ATOM 640 CD1 LEU B 23 20.740 -17.255 13.102 1.00 12.66 C +ATOM 641 CD2 LEU B 23 18.435 -17.811 12.505 1.00 8.94 C +ATOM 642 N GLU B 24 21.793 -21.677 13.122 1.00 16.36 N +ATOM 643 CA GLU B 24 22.257 -22.403 14.301 1.00 15.37 C +ATOM 644 C GLU B 24 23.775 -22.524 14.299 1.00 14.17 C +ATOM 645 O GLU B 24 24.424 -22.289 15.314 1.00 13.50 O +ATOM 646 CB GLU B 24 21.639 -23.788 14.313 1.00 16.34 C +ATOM 647 CG GLU B 24 20.119 -23.714 14.438 1.00 19.60 C +ATOM 648 CD GLU B 24 19.310 -24.940 14.017 1.00 19.00 C +ATOM 649 OE1 GLU B 24 19.828 -25.841 13.354 1.00 23.40 O +ATOM 650 OE2 GLU B 24 18.128 -24.980 14.352 1.00 21.12 O +ATOM 651 N LYS B 25 24.342 -22.826 13.122 1.00 14.02 N +ATOM 652 CA LYS B 25 25.782 -22.977 12.956 1.00 13.50 C +ATOM 653 C LYS B 25 26.534 -21.670 13.118 1.00 11.19 C +ATOM 654 O LYS B 25 27.600 -21.635 13.719 1.00 12.53 O +ATOM 655 CB LYS B 25 26.106 -23.546 11.580 1.00 14.36 C +ATOM 656 CG LYS B 25 25.640 -24.970 11.374 1.00 10.68 C +ATOM 657 CD LYS B 25 26.091 -25.411 9.997 1.00 15.06 C +ATOM 658 CE LYS B 25 25.513 -26.772 9.654 1.00 18.25 C +ATOM 659 NZ LYS B 25 26.025 -27.813 10.525 1.00 19.94 N +ATOM 660 N LEU B 26 25.974 -20.584 12.587 1.00 10.31 N +ATOM 661 CA LEU B 26 26.543 -19.252 12.713 1.00 10.91 C +ATOM 662 C LEU B 26 26.501 -18.818 14.170 1.00 11.18 C +ATOM 663 O LEU B 26 27.480 -18.277 14.681 1.00 11.74 O +ATOM 664 CB LEU B 26 25.741 -18.301 11.832 1.00 11.12 C +ATOM 665 CG LEU B 26 26.290 -17.819 10.482 1.00 13.51 C +ATOM 666 CD1 LEU B 26 27.290 -18.794 9.859 1.00 13.07 C +ATOM 667 CD2 LEU B 26 25.096 -17.605 9.578 1.00 13.69 C +ATOM 668 N ASN B 27 25.398 -19.144 14.860 1.00 11.53 N +ATOM 669 CA ASN B 27 25.244 -18.871 16.281 1.00 13.22 C +ATOM 670 C ASN B 27 26.240 -19.680 17.122 1.00 12.73 C +ATOM 671 O ASN B 27 26.770 -19.118 18.080 1.00 14.91 O +ATOM 672 CB ASN B 27 23.801 -19.186 16.692 1.00 12.88 C +ATOM 673 CG ASN B 27 23.445 -18.820 18.129 1.00 13.87 C +ATOM 674 OD1 ASN B 27 22.959 -19.656 18.892 1.00 15.19 O +ATOM 675 ND2 ASN B 27 23.659 -17.575 18.549 1.00 8.54 N +ATOM 676 N GLU B 28 26.568 -20.950 16.814 1.00 11.80 N +ATOM 677 CA GLU B 28 27.589 -21.681 17.569 1.00 12.92 C +ATOM 678 C GLU B 28 28.989 -21.106 17.385 1.00 14.52 C +ATOM 679 O GLU B 28 29.797 -21.070 18.321 1.00 14.94 O +ATOM 680 CB GLU B 28 27.661 -23.146 17.169 1.00 13.50 C +ATOM 681 CG GLU B 28 26.454 -23.942 17.618 1.00 21.50 C +ATOM 682 CD GLU B 28 26.172 -23.965 19.124 1.00 26.41 C +ATOM 683 OE1 GLU B 28 24.992 -23.917 19.484 1.00 25.13 O +ATOM 684 OE2 GLU B 28 27.107 -24.047 19.933 1.00 26.19 O +ATOM 685 N LEU B 29 29.252 -20.625 16.163 1.00 12.67 N +ATOM 686 CA LEU B 29 30.502 -19.969 15.843 1.00 12.77 C +ATOM 687 C LEU B 29 30.619 -18.573 16.444 1.00 13.04 C +ATOM 688 O LEU B 29 31.711 -18.013 16.441 1.00 14.01 O +ATOM 689 CB LEU B 29 30.650 -19.888 14.325 1.00 12.68 C +ATOM 690 CG LEU B 29 31.491 -20.864 13.485 1.00 9.89 C +ATOM 691 CD1 LEU B 29 31.954 -22.083 14.257 1.00 7.19 C +ATOM 692 CD2 LEU B 29 30.627 -21.253 12.301 1.00 8.10 C +ATOM 693 N ASP B 30 29.543 -17.983 16.986 1.00 15.55 N +ATOM 694 CA ASP B 30 29.597 -16.643 17.577 1.00 15.12 C +ATOM 695 C ASP B 30 29.567 -15.533 16.524 1.00 16.40 C +ATOM 696 O ASP B 30 29.726 -14.359 16.856 1.00 17.25 O +ATOM 697 N ALA B 31 29.369 -15.880 15.242 1.00 15.66 N +ATOM 698 CA ALA B 31 29.349 -14.934 14.134 1.00 15.37 C +ATOM 699 C ALA B 31 28.023 -14.176 14.103 1.00 14.97 C +ATOM 700 O ALA B 31 27.077 -14.537 13.404 1.00 15.24 O +ATOM 701 CB ALA B 31 29.564 -15.717 12.838 1.00 12.75 C +ATOM 702 N ASP B 32 27.980 -13.086 14.882 1.00 13.75 N +ATOM 703 CA ASP B 32 26.743 -12.348 15.107 1.00 13.91 C +ATOM 704 C ASP B 32 26.190 -11.464 14.004 1.00 13.40 C +ATOM 705 O ASP B 32 24.968 -11.314 13.902 1.00 15.21 O +ATOM 706 CB ASP B 32 26.902 -11.510 16.381 1.00 11.83 C +ATOM 707 CG ASP B 32 27.066 -12.321 17.668 1.00 10.92 C +ATOM 708 OD1 ASP B 32 26.483 -13.400 17.814 1.00 12.07 O +ATOM 709 OD2 ASP B 32 27.793 -11.856 18.540 1.00 7.97 O +ATOM 710 N GLU B 33 27.044 -10.859 13.172 1.00 12.59 N +ATOM 711 CA GLU B 33 26.560 -10.079 12.045 1.00 10.35 C +ATOM 712 C GLU B 33 25.939 -11.013 10.993 1.00 10.40 C +ATOM 713 O GLU B 33 24.881 -10.725 10.429 1.00 7.74 O +ATOM 714 CB GLU B 33 27.701 -9.308 11.417 1.00 7.98 C +ATOM 715 CG GLU B 33 27.120 -8.406 10.330 1.00 13.75 C +ATOM 716 CD GLU B 33 28.073 -7.810 9.305 1.00 15.40 C +ATOM 717 OE1 GLU B 33 29.235 -8.220 9.236 1.00 15.70 O +ATOM 718 OE2 GLU B 33 27.627 -6.930 8.567 1.00 15.23 O +ATOM 719 N GLN B 34 26.594 -12.161 10.760 1.00 8.44 N +ATOM 720 CA GLN B 34 26.144 -13.146 9.795 1.00 7.38 C +ATOM 721 C GLN B 34 24.876 -13.846 10.271 1.00 5.96 C +ATOM 722 O GLN B 34 24.005 -14.180 9.474 1.00 5.46 O +ATOM 723 CB GLN B 34 27.247 -14.189 9.556 1.00 7.88 C +ATOM 724 CG GLN B 34 28.538 -13.749 8.860 1.00 9.25 C +ATOM 725 CD GLN B 34 29.527 -12.893 9.658 1.00 12.22 C +ATOM 726 OE1 GLN B 34 30.294 -12.133 9.073 1.00 7.48 O +ATOM 727 NE2 GLN B 34 29.587 -12.956 10.992 1.00 14.14 N +ATOM 728 N ALA B 35 24.759 -14.068 11.580 1.00 6.38 N +ATOM 729 CA ALA B 35 23.589 -14.681 12.175 1.00 6.14 C +ATOM 730 C ALA B 35 22.356 -13.789 12.044 1.00 8.27 C +ATOM 731 O ALA B 35 21.251 -14.304 11.851 1.00 7.79 O +ATOM 732 CB ALA B 35 23.872 -14.956 13.642 1.00 6.39 C +ATOM 733 N ASP B 36 22.515 -12.453 12.104 1.00 9.52 N +ATOM 734 CA ASP B 36 21.401 -11.529 11.885 1.00 10.95 C +ATOM 735 C ASP B 36 20.886 -11.590 10.458 1.00 8.74 C +ATOM 736 O ASP B 36 19.680 -11.665 10.221 1.00 10.77 O +ATOM 737 CB ASP B 36 21.796 -10.073 12.153 1.00 14.44 C +ATOM 738 CG ASP B 36 21.937 -9.645 13.611 1.00 19.15 C +ATOM 739 OD1 ASP B 36 21.387 -10.292 14.507 1.00 18.96 O +ATOM 740 OD2 ASP B 36 22.600 -8.633 13.842 1.00 23.45 O +ATOM 741 N ILE B 37 21.826 -11.571 9.506 1.00 5.82 N +ATOM 742 CA ILE B 37 21.513 -11.644 8.086 1.00 5.19 C +ATOM 743 C ILE B 37 20.844 -12.984 7.756 1.00 7.30 C +ATOM 744 O ILE B 37 19.967 -13.037 6.888 1.00 10.47 O +ATOM 745 CB ILE B 37 22.826 -11.467 7.246 1.00 2.63 C +ATOM 746 CG1 ILE B 37 23.520 -10.136 7.567 1.00 2.00 C +ATOM 747 CG2 ILE B 37 22.473 -11.505 5.755 1.00 2.00 C +ATOM 748 CD1 ILE B 37 24.898 -9.946 6.900 1.00 2.00 C +ATOM 749 N CYS B 38 21.217 -14.070 8.450 1.00 2.91 N +ATOM 750 CA CYS B 38 20.642 -15.372 8.179 1.00 3.87 C +ATOM 751 C CYS B 38 19.260 -15.513 8.806 1.00 7.45 C +ATOM 752 O CYS B 38 18.423 -16.253 8.285 1.00 10.13 O +ATOM 753 CB CYS B 38 21.552 -16.449 8.710 1.00 2.00 C +ATOM 754 SG CYS B 38 21.174 -18.052 7.970 1.00 2.31 S +ATOM 755 N GLU B 39 18.989 -14.802 9.914 1.00 8.46 N +ATOM 756 CA GLU B 39 17.676 -14.782 10.544 1.00 8.84 C +ATOM 757 C GLU B 39 16.722 -14.102 9.568 1.00 8.59 C +ATOM 758 O GLU B 39 15.628 -14.596 9.292 1.00 6.94 O +ATOM 759 CB GLU B 39 17.764 -14.003 11.858 1.00 10.88 C +ATOM 760 CG GLU B 39 16.569 -14.034 12.798 1.00 16.77 C +ATOM 761 CD GLU B 39 15.327 -13.299 12.297 1.00 22.83 C +ATOM 762 OE1 GLU B 39 14.354 -13.958 11.928 1.00 23.90 O +ATOM 763 OE2 GLU B 39 15.338 -12.069 12.261 1.00 26.57 O +ATOM 764 N SER B 40 17.153 -12.954 9.042 1.00 8.47 N +ATOM 765 CA SER B 40 16.377 -12.215 8.067 1.00 9.69 C +ATOM 766 C SER B 40 16.184 -13.008 6.780 1.00 8.88 C +ATOM 767 O SER B 40 15.105 -12.968 6.182 1.00 10.30 O +ATOM 768 CB SER B 40 17.086 -10.917 7.783 1.00 9.72 C +ATOM 769 OG SER B 40 16.371 -10.190 6.804 1.00 14.95 O +ATOM 770 N LEU B 41 17.215 -13.767 6.375 1.00 9.50 N +ATOM 771 CA LEU B 41 17.151 -14.615 5.187 1.00 9.04 C +ATOM 772 C LEU B 41 16.108 -15.707 5.394 1.00 5.60 C +ATOM 773 O LEU B 41 15.363 -16.058 4.486 1.00 4.08 O +ATOM 774 CB LEU B 41 18.525 -15.250 4.905 1.00 7.83 C +ATOM 775 CG LEU B 41 18.697 -16.050 3.606 1.00 5.40 C +ATOM 776 CD1 LEU B 41 18.503 -15.140 2.445 1.00 2.00 C +ATOM 777 CD2 LEU B 41 20.085 -16.627 3.488 1.00 4.76 C +ATOM 778 N HIS B 42 16.012 -16.213 6.619 1.00 7.35 N +ATOM 779 CA HIS B 42 15.003 -17.192 6.973 1.00 7.09 C +ATOM 780 C HIS B 42 13.610 -16.545 6.956 1.00 5.80 C +ATOM 781 O HIS B 42 12.618 -17.238 6.742 1.00 3.81 O +ATOM 782 CB HIS B 42 15.376 -17.752 8.346 1.00 3.84 C +ATOM 783 CG HIS B 42 14.291 -18.649 8.916 1.00 9.66 C +ATOM 784 ND1 HIS B 42 13.192 -18.249 9.546 1.00 10.01 N +ATOM 785 CD2 HIS B 42 14.258 -20.015 8.832 1.00 9.42 C +ATOM 786 CE1 HIS B 42 12.494 -19.309 9.843 1.00 9.52 C +ATOM 787 NE2 HIS B 42 13.146 -20.358 9.411 1.00 11.61 N +ATOM 788 N ASP B 43 13.482 -15.231 7.166 1.00 8.83 N +ATOM 789 CA ASP B 43 12.187 -14.579 7.021 1.00 15.32 C +ATOM 790 C ASP B 43 11.759 -14.573 5.561 1.00 14.58 C +ATOM 791 O ASP B 43 10.613 -14.903 5.266 1.00 14.63 O +ATOM 792 CB ASP B 43 12.233 -13.134 7.539 1.00 17.05 C +ATOM 793 CG ASP B 43 12.354 -13.002 9.057 1.00 21.50 C +ATOM 794 OD1 ASP B 43 11.975 -13.929 9.786 1.00 21.49 O +ATOM 795 OD2 ASP B 43 12.822 -11.954 9.511 1.00 20.93 O +ATOM 796 N HIS B 44 12.685 -14.283 4.633 1.00 15.21 N +ATOM 797 CA HIS B 44 12.378 -14.278 3.207 1.00 13.85 C +ATOM 798 C HIS B 44 12.104 -15.674 2.658 1.00 12.25 C +ATOM 799 O HIS B 44 11.174 -15.875 1.874 1.00 11.01 O +ATOM 800 CB HIS B 44 13.541 -13.615 2.447 1.00 16.78 C +ATOM 801 CG HIS B 44 13.704 -12.131 2.777 1.00 25.42 C +ATOM 802 ND1 HIS B 44 13.590 -11.515 3.958 1.00 28.26 N +ATOM 803 CD2 HIS B 44 14.005 -11.163 1.851 1.00 28.03 C +ATOM 804 CE1 HIS B 44 13.807 -10.235 3.785 1.00 27.39 C +ATOM 805 NE2 HIS B 44 14.056 -10.036 2.515 1.00 28.86 N +ATOM 806 N ALA B 45 12.884 -16.655 3.129 1.00 10.85 N +ATOM 807 CA ALA B 45 12.755 -18.052 2.745 1.00 11.04 C +ATOM 808 C ALA B 45 11.399 -18.632 3.127 1.00 10.84 C +ATOM 809 O ALA B 45 10.837 -19.437 2.384 1.00 15.00 O +ATOM 810 CB ALA B 45 13.846 -18.873 3.420 1.00 8.89 C +ATOM 811 N ASP B 46 10.881 -18.198 4.281 1.00 9.71 N +ATOM 812 CA ASP B 46 9.543 -18.538 4.752 1.00 10.47 C +ATOM 813 C ASP B 46 8.463 -18.006 3.827 1.00 9.61 C +ATOM 814 O ASP B 46 7.579 -18.757 3.416 1.00 8.88 O +ATOM 815 CB ASP B 46 9.258 -17.947 6.125 1.00 13.48 C +ATOM 816 CG ASP B 46 9.089 -18.980 7.221 1.00 19.52 C +ATOM 817 OD1 ASP B 46 8.338 -19.948 7.031 1.00 19.08 O +ATOM 818 OD2 ASP B 46 9.712 -18.793 8.267 1.00 20.83 O +ATOM 819 N GLU B 47 8.556 -16.710 3.496 1.00 6.82 N +ATOM 820 CA GLU B 47 7.602 -16.053 2.628 1.00 10.17 C +ATOM 821 C GLU B 47 7.555 -16.709 1.249 1.00 9.46 C +ATOM 822 O GLU B 47 6.467 -16.867 0.685 1.00 11.70 O +ATOM 823 CB GLU B 47 7.988 -14.582 2.526 1.00 11.98 C +ATOM 824 CG GLU B 47 7.065 -13.654 1.711 1.00 14.19 C +ATOM 825 CD GLU B 47 7.605 -12.238 1.441 1.00 16.74 C +ATOM 826 OE1 GLU B 47 8.480 -11.757 2.170 1.00 18.96 O +ATOM 827 OE2 GLU B 47 7.145 -11.603 0.489 1.00 13.52 O +ATOM 828 N LEU B 48 8.709 -17.130 0.703 1.00 8.17 N +ATOM 829 CA LEU B 48 8.729 -17.837 -0.572 1.00 6.30 C +ATOM 830 C LEU B 48 8.155 -19.253 -0.436 1.00 6.64 C +ATOM 831 O LEU B 48 7.442 -19.679 -1.341 1.00 8.49 O +ATOM 832 CB LEU B 48 10.157 -17.929 -1.124 1.00 4.00 C +ATOM 833 CG LEU B 48 10.317 -18.711 -2.441 1.00 4.25 C +ATOM 834 CD1 LEU B 48 9.639 -17.945 -3.561 1.00 2.00 C +ATOM 835 CD2 LEU B 48 11.781 -18.936 -2.751 1.00 2.00 C +ATOM 836 N TYR B 49 8.423 -20.012 0.643 1.00 6.07 N +ATOM 837 CA TYR B 49 7.836 -21.337 0.819 1.00 7.97 C +ATOM 838 C TYR B 49 6.313 -21.245 0.907 1.00 10.13 C +ATOM 839 O TYR B 49 5.623 -22.076 0.327 1.00 11.54 O +ATOM 840 CB TYR B 49 8.376 -22.002 2.092 1.00 7.73 C +ATOM 841 CG TYR B 49 7.750 -23.371 2.344 1.00 9.31 C +ATOM 842 CD1 TYR B 49 8.000 -24.421 1.462 1.00 6.17 C +ATOM 843 CD2 TYR B 49 6.871 -23.552 3.423 1.00 10.75 C +ATOM 844 CE1 TYR B 49 7.366 -25.642 1.644 1.00 5.56 C +ATOM 845 CE2 TYR B 49 6.237 -24.780 3.608 1.00 8.46 C +ATOM 846 CZ TYR B 49 6.487 -25.819 2.711 1.00 9.04 C +ATOM 847 OH TYR B 49 5.831 -27.032 2.852 1.00 7.92 O +ATOM 848 N ARG B 50 5.773 -20.242 1.611 1.00 11.42 N +ATOM 849 CA ARG B 50 4.345 -20.021 1.708 1.00 10.99 C +ATOM 850 C ARG B 50 3.747 -19.692 0.349 1.00 11.38 C +ATOM 851 O ARG B 50 2.698 -20.215 -0.018 1.00 13.65 O +ATOM 852 CB ARG B 50 4.065 -18.880 2.676 1.00 13.45 C +ATOM 853 CG ARG B 50 4.328 -19.280 4.107 1.00 18.51 C +ATOM 854 CD ARG B 50 3.841 -18.218 5.084 1.00 26.36 C +ATOM 855 NE ARG B 50 4.014 -18.699 6.451 1.00 34.72 N +ATOM 856 CZ ARG B 50 3.075 -19.416 7.094 1.00 37.19 C +ATOM 857 NH1 ARG B 50 1.904 -19.732 6.527 1.00 35.63 N +ATOM 858 NH2 ARG B 50 3.332 -19.860 8.325 1.00 37.64 N +ATOM 859 N SER B 51 4.450 -18.862 -0.427 1.00 12.32 N +ATOM 860 CA SER B 51 4.032 -18.472 -1.768 1.00 11.28 C +ATOM 861 C SER B 51 4.002 -19.653 -2.736 1.00 10.82 C +ATOM 862 O SER B 51 3.060 -19.811 -3.506 1.00 11.75 O +ATOM 863 CB SER B 51 4.995 -17.412 -2.249 1.00 10.05 C +ATOM 864 OG SER B 51 4.644 -16.876 -3.509 1.00 8.47 O +ATOM 865 N CYS B 52 5.033 -20.505 -2.687 1.00 12.15 N +ATOM 866 CA CYS B 52 5.138 -21.696 -3.522 1.00 10.83 C +ATOM 867 C CYS B 52 4.141 -22.751 -3.103 1.00 11.15 C +ATOM 868 O CYS B 52 3.612 -23.468 -3.938 1.00 13.08 O +ATOM 869 CB CYS B 52 6.515 -22.319 -3.426 1.00 8.27 C +ATOM 870 SG CYS B 52 7.787 -21.347 -4.257 1.00 6.53 S +ATOM 871 N LEU B 53 3.862 -22.852 -1.806 1.00 12.33 N +ATOM 872 CA LEU B 53 2.923 -23.830 -1.291 1.00 14.23 C +ATOM 873 C LEU B 53 1.512 -23.440 -1.709 1.00 15.02 C +ATOM 874 O LEU B 53 0.684 -24.305 -1.996 1.00 17.10 O +ATOM 875 CB LEU B 53 3.081 -23.861 0.217 1.00 13.72 C +ATOM 876 CG LEU B 53 2.504 -24.981 1.038 1.00 15.56 C +ATOM 877 CD1 LEU B 53 3.060 -26.323 0.595 1.00 15.66 C +ATOM 878 CD2 LEU B 53 2.843 -24.707 2.494 1.00 14.83 C +ATOM 879 N ALA B 54 1.260 -22.126 -1.800 1.00 13.27 N +ATOM 880 CA ALA B 54 -0.023 -21.601 -2.236 1.00 13.34 C +ATOM 881 C ALA B 54 -0.290 -21.891 -3.707 1.00 14.53 C +ATOM 882 O ALA B 54 -1.415 -22.220 -4.086 1.00 16.40 O +ATOM 883 CB ALA B 54 -0.073 -20.094 -2.042 1.00 9.30 C +ATOM 884 N ARG B 55 0.753 -21.814 -4.541 1.00 12.87 N +ATOM 885 CA ARG B 55 0.594 -22.018 -5.966 1.00 11.51 C +ATOM 886 C ARG B 55 0.678 -23.464 -6.445 1.00 11.97 C +ATOM 887 O ARG B 55 -0.041 -23.868 -7.361 1.00 12.41 O +ATOM 888 CB ARG B 55 1.645 -21.186 -6.690 1.00 12.41 C +ATOM 889 CG ARG B 55 1.291 -20.989 -8.160 1.00 14.85 C +ATOM 890 CD ARG B 55 2.373 -20.213 -8.870 1.00 16.01 C +ATOM 891 NE ARG B 55 1.956 -19.853 -10.212 1.00 17.42 N +ATOM 892 CZ ARG B 55 1.701 -18.587 -10.556 1.00 18.15 C +ATOM 893 NH1 ARG B 55 1.813 -17.565 -9.701 1.00 18.52 N +ATOM 894 NH2 ARG B 55 1.321 -18.345 -11.804 1.00 21.48 N +ATOM 895 N PHE B 56 1.561 -24.242 -5.815 1.00 9.82 N +ATOM 896 CA PHE B 56 1.887 -25.589 -6.252 1.00 9.46 C +ATOM 897 C PHE B 56 1.502 -26.689 -5.277 1.00 10.67 C +ATOM 898 O PHE B 56 1.669 -27.870 -5.593 1.00 10.68 O +ATOM 899 CB PHE B 56 3.385 -25.712 -6.507 1.00 9.05 C +ATOM 900 CG PHE B 56 4.008 -24.625 -7.364 1.00 8.23 C +ATOM 901 CD1 PHE B 56 3.478 -24.318 -8.622 1.00 8.04 C +ATOM 902 CD2 PHE B 56 5.124 -23.943 -6.879 1.00 6.87 C +ATOM 903 CE1 PHE B 56 4.071 -23.322 -9.397 1.00 8.69 C +ATOM 904 CE2 PHE B 56 5.708 -22.947 -7.662 1.00 10.56 C +ATOM 905 CZ PHE B 56 5.186 -22.634 -8.920 1.00 11.49 C +ATOM 906 N GLY B 57 0.993 -26.324 -4.092 1.00 12.16 N +ATOM 907 CA GLY B 57 0.605 -27.287 -3.071 1.00 13.29 C +ATOM 908 C GLY B 57 -0.705 -28.025 -3.344 1.00 14.32 C +ATOM 909 O GLY B 57 -1.387 -27.745 -4.335 1.00 13.20 O +TER 910 GLY B 57 +HETATM 911 O HOH A 64 2.118 -13.887 -16.763 1.00 11.68 O +HETATM 912 O HOH A 65 15.078 -8.511 -5.953 1.00 15.82 O +HETATM 913 O HOH A 66 18.532 -28.676 -6.883 1.00 15.23 O +HETATM 914 O HOH A 67 15.384 -12.829 -12.947 1.00 26.71 O +HETATM 915 O HOH A 68 29.391 -25.299 11.585 1.00 23.37 O +HETATM 916 O HOH A 69 0.087 -15.314 -7.027 1.00 50.65 O +HETATM 917 O HOH A 70 23.354 -17.746 1.445 1.00 12.57 O +HETATM 918 O HOH A 71 24.880 -9.242 -2.653 1.00 16.08 O +HETATM 919 O HOH A 72 38.775 -17.703 8.841 1.00 26.21 O +HETATM 920 O HOH A 73 29.291 -20.576 -5.787 1.00 27.49 O +HETATM 921 O HOH A 74 40.005 -27.643 14.257 1.00 36.82 O +HETATM 922 O HOH A 75 19.876 -5.665 1.848 1.00 27.90 O +HETATM 923 O HOH A 76 34.437 -16.876 -4.376 1.00 33.80 O +HETATM 924 O HOH A 77 32.595 -12.075 -2.624 1.00 26.30 O +HETATM 925 O HOH A 78 26.022 -22.355 -8.666 1.00 32.90 O +HETATM 926 O HOH A 79 16.340 -29.900 -9.246 1.00 34.31 O +HETATM 927 O HOH A 80 2.132 -15.237 -11.738 1.00 41.14 O +HETATM 928 O HOH A 81 30.644 -11.047 15.315 1.00 45.21 O +HETATM 929 O HOH A 82 18.525 -26.829 -13.044 1.00 32.46 O +HETATM 930 O HOH A 83 33.335 -12.415 -7.134 1.00 36.35 O +HETATM 931 O HOH A 84 12.593 -28.465 -12.935 1.00 40.48 O +HETATM 932 O HOH A 85 8.309 -12.381 -12.207 1.00 45.42 O +HETATM 933 O HOH B 64 11.558 -31.773 -12.106 1.00 30.61 O +HETATM 934 O HOH B 65 -2.528 -30.362 -4.998 1.00 25.65 O +HETATM 935 O HOH B 66 28.929 -23.970 13.988 1.00 14.02 O +HETATM 936 O HOH B 67 25.028 -25.985 14.453 1.00 15.65 O +HETATM 937 O HOH B 68 23.901 -26.155 17.059 1.00 31.84 O +HETATM 938 O HOH B 69 23.854 -20.103 21.868 1.00 15.00 O +HETATM 939 O HOH B 70 18.705 -11.330 4.787 1.00 28.30 O +HETATM 940 O HOH B 71 -1.188 -16.234 -9.645 1.00 41.59 O +HETATM 941 O HOH B 72 9.734 -34.401 0.031 1.00 38.62 O +HETATM 942 O HOH B 73 32.880 -16.675 14.403 1.00 30.51 O +HETATM 943 O HOH B 74 18.102 -28.328 6.990 1.00 32.80 O +MASTER 275 0 0 4 0 0 0 6 941 2 0 10 +END diff --git a/tests/test_structure.py b/tests/test_structure.py new file mode 100644 index 00000000..458c74d6 --- /dev/null +++ b/tests/test_structure.py @@ -0,0 +1,87 @@ +""" +Tests for PDB repair and Structure auto-repair logic. + +Uses 6u5e.pdb (complete) and 2GHY.pdb (incomplete — missing residue) as test data. +""" +import pytest +from pathlib import Path +import frustratometer + +test_data_path = Path(__file__).parent / 'data' + + +@pytest.mark.parametrize("pdb,chain,repair_pdb,expect_repair", [ + ("6u5e.pdb", "A", None, False), # complete, auto-detect → no repair needed + ("6u5e.pdb", "A", False, False), # complete, skip repair → fine + ("6u5e.pdb", "A", True, True), # complete, force repair → calls pdbfixer + ("2GHY.pdb", "A", None, True), # incomplete, auto-detect → repairs automatically + ("2GHY.pdb", "A", True, True), # incomplete, force repair → calls pdbfixer +]) +def test_structure_valid(pdb, chain, repair_pdb, expect_repair, tmp_path): + """Structure should be consistent and only call PDBFixer when expected.""" + s = frustratometer.Structure(test_data_path / pdb, chain, + repair_pdb=repair_pdb, pdb_directory=tmp_path) + assert len(s.sequence) == s.distance_matrix.shape[0] + cleaned_files = list(tmp_path.glob("*_cleaned.pdb")) + was_repaired = len(cleaned_files) > 0 + assert was_repaired == expect_repair, ( + f"Expected PDBFixer {'to be' if expect_repair else 'not to be'} called" + ) + + +def test_incomplete_pdb_no_repair_raises(): + """An incomplete PDB with repair_pdb=False should raise an informative error.""" + with pytest.raises(ValueError, match="repair_pdb=True"): + frustratometer.Structure(test_data_path / '2GHY.pdb', 'A', repair_pdb=False) + + +def test_repair_pdb_no_memory_leak(tmp_path): + """Repairing multiple PDBs should not leak memory significantly.""" + import resource + from frustratometer.pdb import repair_pdb + + # Warm up (first call loads OpenMM libs) + repair_pdb(test_data_path / '6u5e.pdb', 'A', tmp_path) + baseline_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + + for i in range(3): + repair_pdb(test_data_path / '6u5e.pdb', 'A', tmp_path) + + final_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + growth_mb = (final_kb - baseline_kb) / 1024 + # Each uncontained leak is ~170 MB; 3 calls would be ~510 MB. + # With multiprocessing isolation the parent process doesn't grow. + assert growth_mb < 200, f"Memory grew by {growth_mb:.0f} MB over 3 repairs — possible leak" + + +@pytest.mark.memory_heavy +def test_pdbfixer_leaks_without_isolation(tmp_path): + """Canary: calling PDBFixer in-process DOES leak memory. + + Good news: If this test starts failing, pdbfixer/OpenMM may have fixed their leak and + the multiprocessing isolation in fix.py can be removed. + """ + import gc + import resource + from frustratometer.pdb.fix import _repair_worker + + pdb = str(test_data_path / '6u5e.pdb') + out = str(tmp_path / 'cleaned.pdb') + + # Warm up + _repair_worker(pdb, 'A', out) + gc.collect() + baseline_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + + for _ in range(3): + _repair_worker(pdb, 'A', out) + gc.collect() + + final_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + growth_mb = (final_kb - baseline_kb) / 1024 + # Expect significant growth (~170 MB per call) when running in-process. + # If this fails (<200 MB), the leak is fixed upstream — great news! + assert growth_mb >= 200, ( + f"Memory only grew {growth_mb:.0f} MB. PDBFixer leak may have been fixed. " + f"Consider removing multiprocessing isolation in fix.py." + ) From ac30451543aa6a0611808be090d860216d737604 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 6 Apr 2026 17:27:04 -0500 Subject: [PATCH 02/28] Adds method to load multiple structures in parallel --- frustratometer/classes/Structure.py | 50 +++++++++++++++++++++++++++++ frustratometer/pdb/__init__.py | 4 +-- frustratometer/pdb/fix.py | 39 +++++++++++++++++++++- tests/test_structure.py | 19 +++++++++++ 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index 41b7f3d7..b805a66d 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -224,6 +224,56 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self.full_to_aligned_index_dict=dict(zip(range(self.init_index_shift,self.fin_index_shift+1), range(len(self.sequence)))) self.mapped_distance_matrix=self.distance_matrix + @classmethod + def from_pdb_list(cls, pdb_files, chain=None, pdb_directory=None, repair_pdb=None, **kwargs): + """Build multiple Structures, repairing PDBs in parallel when needed. + + Parameters + ---------- + pdb_files : list of str or Path + PDB/CIF file paths. + chain : str or None + Chain to use for all structures. + pdb_directory : Path, optional + Directory for repaired files. + repair_pdb : bool or None + True → repair all in parallel, then build. + False → build all without repair. + None (default) → build without repair first; batch-repair + only the ones that fail validation, then rebuild those. + **kwargs + Extra keyword arguments passed to each Structure(). + + Returns + ------- + list[Structure] + """ + if pdb_directory is None: + pdb_directory = Path(tempfile.gettempdir()) + + if repair_pdb is True: + cleaned = pdb.repair_pdbs([(f, chain) for f in pdb_files], pdb_directory) + return [cls(p, chain, repair_pdb=False, **kwargs) for p in cleaned] + + if repair_pdb is False: + return [cls(f, chain, repair_pdb=False, **kwargs) for f in pdb_files] + + # Auto-detect: try without repair, batch-repair failures + structures = {} + needs_repair = [] + for f in pdb_files: + try: + structures[str(f)] = cls(f, chain, repair_pdb=False, **kwargs) + except ValueError: + needs_repair.append(f) + + if needs_repair: + cleaned = pdb.repair_pdbs([(f, chain) for f in needs_repair], pdb_directory) + for f, p in zip(needs_repair, cleaned): + structures[str(f)] = cls(p, chain, repair_pdb=False, **kwargs) + + return [structures[str(f)] for f in pdb_files] + @classmethod def full_pdb(cls,pdb_file: Union[Path,str], chain: Union[str,None]=None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None): diff --git a/frustratometer/pdb/__init__.py b/frustratometer/pdb/__init__.py index 28f61071..2ae96247 100644 --- a/frustratometer/pdb/__init__.py +++ b/frustratometer/pdb/__init__.py @@ -14,7 +14,7 @@ from .pdb import * try: - from .fix import repair_pdb + from .fix import repair_pdb, repair_pdbs except ImportError as e: error_message=str(e) if 'pdbfixer' in str(e): @@ -33,4 +33,4 @@ def warn_pdbfixer_not_installed(): else: raise e -__all__ = ['download', 'get_sequence', 'get_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb'] \ No newline at end of file +__all__ = ['download', 'get_sequence', 'get_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs'] \ No newline at end of file diff --git a/frustratometer/pdb/fix.py b/frustratometer/pdb/fix.py index f3f6f592..cc07d1a0 100644 --- a/frustratometer/pdb/fix.py +++ b/frustratometer/pdb/fix.py @@ -88,4 +88,41 @@ def repair_pdb(pdb_file: str, chain: str, pdb_directory: Path = None) -> Path: f"PDB repair failed for {pdb_file.name} (exit code {process.exitcode})" ) - return cleaned_path \ No newline at end of file + return cleaned_path + + +def repair_pdbs(jobs, pdb_directory: Path = None) -> list: + """ + Repair multiple PDB files in parallel. + + Each repair runs in its own process, so OpenMM memory is fully + reclaimed after each one. + + Parameters + ---------- + jobs : list of (pdb_file, chain) tuples + Each element is ``(pdb_file, chain)`` where *chain* can be None. + pdb_directory : Path, optional + Directory for cleaned output files. Defaults to the system temp dir. + + Returns + ------- + list[Path] + Paths to the repaired PDB files, in the same order as *jobs*. + """ + if pdb_directory is None: + pdb_directory = Path(tempfile.gettempdir()) + pdb_directory = Path(pdb_directory) + + worker_args = [] + cleaned_paths = [] + for pdb_file, chain in jobs: + pdb_file = Path(pdb_file) + cleaned = pdb_directory / f"{pdb_file.stem}_cleaned.pdb" + cleaned_paths.append(cleaned) + worker_args.append((str(pdb_file), chain, str(cleaned))) + + with multiprocessing.Pool() as pool: + pool.starmap(_repair_worker, worker_args) + + return cleaned_paths \ No newline at end of file diff --git a/tests/test_structure.py b/tests/test_structure.py index 458c74d6..163c5c55 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -35,6 +35,25 @@ def test_incomplete_pdb_no_repair_raises(): frustratometer.Structure(test_data_path / '2GHY.pdb', 'A', repair_pdb=False) +@pytest.mark.parametrize("repair_pdb", [None, True, False]) +def test_from_pdb_list(repair_pdb, tmp_path): + """Load multiple PDBs via from_pdb_list with different repair modes.""" + pdb_files = [test_data_path / '6u5e.pdb', test_data_path / '2GHY.pdb'] + if repair_pdb is False: + # 2GHY is incomplete → False should fail + with pytest.raises(ValueError, match="repair_pdb=True"): + frustratometer.Structure.from_pdb_list(pdb_files, 'A', + pdb_directory=tmp_path, + repair_pdb=False) + else: + structures = frustratometer.Structure.from_pdb_list(pdb_files, 'A', + pdb_directory=tmp_path, + repair_pdb=repair_pdb) + assert len(structures) == 2 + for s in structures: + assert len(s.sequence) == s.distance_matrix.shape[0] + + def test_repair_pdb_no_memory_leak(tmp_path): """Repairing multiple PDBs should not leak memory significantly.""" import resource From 273ea972e375ac6aeaa83f80e965ad1620306616 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 6 Apr 2026 22:03:03 -0500 Subject: [PATCH 03/28] Adds sparse distance calculation --- frustratometer/classes/DCA.py | 2 +- frustratometer/classes/Structure.py | 22 ++- frustratometer/pdb/__init__.py | 5 +- frustratometer/pdb/distance.py | 236 ++++++++++++++++++++++++++++ frustratometer/pdb/pdb.py | 86 ---------- tests/test_dca_frustratometer.py | 8 +- tests/test_sparse_distance.py | 59 +++++++ 7 files changed, 318 insertions(+), 100 deletions(-) create mode 100644 frustratometer/pdb/distance.py create mode 100644 tests/test_sparse_distance.py diff --git a/frustratometer/classes/DCA.py b/frustratometer/classes/DCA.py index e2ffc33f..06767229 100644 --- a/frustratometer/classes/DCA.py +++ b/frustratometer/classes/DCA.py @@ -526,7 +526,7 @@ def distance_matrix_method(self): @distance_matrix_method.setter def distance_matrix_method(self, value): - self.distance_matrix = pdb.get_distance_matrix(self._pdb_file, self._chain, value) + self.distance_matrix = pdb.get_full_distance_matrix(self._pdb_file, self._chain, value) self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff) self._distance_matrix_method = value self._native_energy = None diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index b805a66d..d06c7ece 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -18,7 +18,7 @@ class Structure: def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_selection: str = None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, - distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None)->object: + distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None, sparse: bool = True)->object: """ Generates structure object. Both PDB and CIF format files are accepted as input. @@ -75,18 +75,18 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s try: self._init_structure(pdb_file, chain, seq_selection, aligned_sequence, filtered_aligned_sequence, distance_matrix_method, - pdb_directory, repair_pdb=False) + pdb_directory, repair_pdb=False, sparse=sparse) self._validate_structure() except Exception as e: logger.info("Structure validation failed without repair (%s), retrying with repair_pdb=True", e) self._init_structure(pdb_file, chain, seq_selection, aligned_sequence, filtered_aligned_sequence, distance_matrix_method, - pdb_directory, repair_pdb=True) + pdb_directory, repair_pdb=True, sparse=sparse) self._validate_structure() else: self._init_structure(pdb_file, chain, seq_selection, aligned_sequence, filtered_aligned_sequence, distance_matrix_method, - pdb_directory, repair_pdb=repair_pdb) + pdb_directory, repair_pdb=repair_pdb, sparse=sparse) self._validate_structure() def _validate_structure(self): @@ -101,7 +101,7 @@ def _validate_structure(self): def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, filtered_aligned_sequence, distance_matrix_method, - pdb_directory, repair_pdb): + pdb_directory, repair_pdb, sparse): try: #Check if file exists @@ -195,10 +195,18 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self.structure=prody.parseMMCIF(str(self.pdb_file),chain=self.chain).select(f"protein and {self.seq_selection}") self.sequence=pdb.get_sequence(self.pdb_file,self.chain) - self.distance_matrix=pdb.get_distance_matrix(pdb_file=self.pdb_file,chain=self.chain, - method=self.distance_matrix_method) + self.distance_matrix=pdb.get_full_distance_matrix(pdb_file=self.pdb_file,chain=self.chain, + method=self.distance_matrix_method) self.full_pdb_distance_matrix=self.distance_matrix + # Compute sparse distance data if requested + if sparse: + self.sparse_distance_data = pdb.get_sparse_distance_matrix( + pdb_file=self.pdb_file, chain=self.chain, + method=self.distance_matrix_method, max_distance=15.0) + else: + self.sparse_distance_data = None + self.z_coordinates=self.structure.select('((name CB) or (resname GLY and name CA))').getCoords() if self.seq_selection!=None: diff --git a/frustratometer/pdb/__init__.py b/frustratometer/pdb/__init__.py index 2ae96247..fdf95946 100644 --- a/frustratometer/pdb/__init__.py +++ b/frustratometer/pdb/__init__.py @@ -5,7 +5,7 @@ If you want to extract the structure's sequence, use the "get_sequence" function. -If you want to extract the distance matrix of the structure's contacts, use the "get_distance_matrix" function. +If you want to extract the distance matrix of the structure's contacts, use the "get_full_distance_matrix" function. If you want to map the full sequence residue positions to the aligned sequence residue positions (may be needed if applying a distance threshold in DCA-related calculations), use the "full_to_filtered_aligned_mapping" function. @@ -13,6 +13,7 @@ """ from .pdb import * +from .distance import get_full_distance_matrix, get_sparse_distance_matrix try: from .fix import repair_pdb, repair_pdbs except ImportError as e: @@ -33,4 +34,4 @@ def warn_pdbfixer_not_installed(): else: raise e -__all__ = ['download', 'get_sequence', 'get_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs'] \ No newline at end of file +__all__ = ['download', 'get_sequence', 'get_full_distance_matrix', 'get_sparse_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs'] \ No newline at end of file diff --git a/frustratometer/pdb/distance.py b/frustratometer/pdb/distance.py new file mode 100644 index 00000000..2631e265 --- /dev/null +++ b/frustratometer/pdb/distance.py @@ -0,0 +1,236 @@ +from pathlib import Path +from typing import Union, Optional, Tuple + +import numpy as np +import scipy.spatial.distance as sdist +from scipy.spatial import cKDTree +import prody +import itertools + + +# --------------------------------------------------------------------------- +# Coordinate selection helpers (one per method) +# --------------------------------------------------------------------------- + +def _parse_structure(pdb_file, chain): + """Parse the structure and construct a chain selection string.""" + structure = prody.parsePDB(str(pdb_file)) + chain_selection = '' if chain is None else f' and chain {chain}' + return structure, chain_selection + + +def _select_ca(structure, chain_selection): + """Select CA atoms.""" + sel = structure.select('protein and name CA' + chain_selection) + if sel is None or sel.numAtoms() == 0: + raise IndexError("Empty selection for distance map (method='CA').") + return sel.getCoords() + + +def _select_cb(structure, chain_selection): + """Select CB atoms, using CA for glycine residues.""" + sel = structure.select( + '(protein and name CB or (resname GLY and name CA))' + chain_selection + ) + if sel is None or sel.numAtoms() == 0: + raise IndexError("Empty selection for distance map (method='CB').") + return sel.getCoords() + + +def _select_cb_force(structure, chain_selection): + """Calculate CB coordinates for all residues, even if CB is missing (e.g. glycine).""" + sel_CA = structure.select('protein and name CA' + chain_selection) + sel_N = structure.select('protein and name N' + chain_selection) + sel_C = structure.select('protein and name C' + chain_selection) + + if sel_CA is None or sel_N is None or sel_C is None: + raise IndexError("Empty selection for CB_force (missing CA/N/C atoms).") + if not (sel_CA.numAtoms() == sel_N.numAtoms() == sel_C.numAtoms()): + raise ValueError("CA, N, and C selections must have the same length for CB_force.") + + CA = sel_CA.getCoords() + N = sel_N.getCoords() + C = sel_C.getCoords() + + v_CA_C = C - CA + v_CA_N = N - CA + v_CA_C /= np.linalg.norm(v_CA_C, axis=1, keepdims=True) + v_CA_N /= np.linalg.norm(v_CA_N, axis=1, keepdims=True) + + cross_CA_C_CA_N = np.cross(v_CA_C, v_CA_N) + cross_CA_C_CA_N /= np.linalg.norm(cross_CA_C_CA_N, axis=1, keepdims=True) + + cross_cross_CA_N = np.cross(cross_CA_C_CA_N, v_CA_N) + cross_cross_CA_N /= np.linalg.norm(cross_cross_CA_N, axis=1, keepdims=True) + + return -0.531020 * v_CA_N - 1.206181 * cross_CA_C_CA_N + 0.789162 * cross_cross_CA_N + CA + + +def _get_residue_coords(structure, chain_selection, method): + """Get representative coordinates for each residue based on the specified method.""" + if method == 'CA': + return _select_ca(structure, chain_selection) + elif method == 'CB': + return _select_cb(structure, chain_selection) + elif method == 'CB_force': + return _select_cb_force(structure, chain_selection) + else: + raise ValueError( + f"Invalid method '{method}'. Accepted methods are 'CA', 'CB', 'minimum', and 'CB_force'." + ) + + +def _full_minimum_distance(structure, chain_selection): + """Calculate the full minimum distance matrix by computing all atom-atom distances and taking minima per residue pair.""" + sel = structure.select('protein' + chain_selection) + if sel is None or sel.numAtoms() == 0: + raise IndexError("Empty selection for distance map (method='minimum').") + coords = sel.getCoords() + distance_matrix = sdist.squareform(sdist.pdist(coords)) + resids = sel.getResindices() + unique_res = np.unique(resids) + selections = np.array([resids == a for a in unique_res]) + n_res = len(unique_res) + dm = np.zeros((n_res, n_res)) + for i, j in itertools.combinations(range(n_res), 2): + d = distance_matrix[selections[i]][:, selections[j]].min() + dm[i, j] = d + dm[j, i] = d + return dm + + +def _sparse_minimum_distance(structure, chain_selection, max_distance): + """Calculate a sparse minimum distance matrix by computing all atom-atom distances and including only pairs within max_distance.""" + sel = structure.select('protein' + chain_selection) + if sel is None or sel.numAtoms() == 0: + raise IndexError("Empty selection for distance map (method='minimum').") + + coords = sel.getCoords() + resindices = sel.getResindices() + + unique_res = np.unique(resindices) + n_res = unique_res.size + res_to_idx = {res: i for i, res in enumerate(unique_res)} + atom_res_idx = np.vectorize(res_to_idx.get)(resindices) + + tree = cKDTree(coords) + pairs = tree.query_pairs(r=max_distance, output_type='ndarray') + if pairs.size == 0: + empty = np.array([], dtype=np.intp) + return empty, empty, np.array([], dtype=float), n_res + + i_atoms = pairs[:, 0] + j_atoms = pairs[:, 1] + dists = np.linalg.norm(coords[i_atoms] - coords[j_atoms], axis=1) + + min_dist = {} + for ia, ja, d in zip(i_atoms, j_atoms, dists): + ri = atom_res_idx[ia] + rj = atom_res_idx[ja] + if ri == rj: + continue + if ri > rj: + ri, rj = rj, ri + key = (ri, rj) + prev = min_dist.get(key) + if prev is None or d < prev: + min_dist[key] = d + + if not min_dist: + empty = np.array([], dtype=np.intp) + return empty, empty, np.array([], dtype=float), n_res + + row_list, col_list, data_list = [], [], [] + for (ri, rj), d in min_dist.items(): + row_list.extend([ri, rj]) + col_list.extend([rj, ri]) + data_list.extend([d, d]) + + return (np.array(row_list, dtype=np.intp), + np.array(col_list, dtype=np.intp), + np.array(data_list, dtype=float), + n_res) + +def _coords_to_sparse(coords, max_distance): + """Calculate a sparse distance matrix from coordinates by including only pairs within max_distance.""" + n = coords.shape[0] + tree = cKDTree(coords) + pairs = tree.query_pairs(r=max_distance, output_type='ndarray') + if pairs.size == 0: + empty = np.array([], dtype=np.intp) + return empty, empty, np.array([], dtype=float), n + + i_idx = pairs[:, 0] + j_idx = pairs[:, 1] + dists = np.linalg.norm(coords[i_idx] - coords[j_idx], axis=1) + + contact_i = np.concatenate([i_idx, j_idx]).astype(np.intp) + contact_j = np.concatenate([j_idx, i_idx]).astype(np.intp) + data = np.concatenate([dists, dists]) + return contact_i, contact_j, data, n + +# --------------------------------------------------------------------------- +# Public API +# --------------------------------------------------------------------------- + +def get_full_distance_matrix( + pdb_file: Union[Path, str], + chain: Optional[str], + method: str = 'CB', +) -> np.ndarray: + """ + Calculate the full (dense) distance matrix of the specified atoms in a PDB file. + + Parameters + ---------- + pdb_file : Path or str + Path to the PDB file. + chain : str or None + Chain ID or chain IDs (space-separated) of the protein. + method : {'CA', 'CB', 'minimum', 'CB_force'} + Method for defining the representative coordinates. + + Returns + ------- + np.ndarray + Symmetric distance matrix of shape (L, L). + """ + structure, chain_selection = _parse_structure(pdb_file, chain) + if method == 'minimum': + return _full_minimum_distance(structure, chain_selection) + coords = _get_residue_coords(structure, chain_selection, method) + return sdist.squareform(sdist.pdist(coords)) + + +def get_sparse_distance_matrix( + pdb_file: Union[Path, str], + chain: Optional[str], + method: str, + max_distance: float, +) -> Tuple[np.ndarray, np.ndarray, np.ndarray, int]: + """ + Calculate a sparse distance matrix of the specified atoms/residues in a PDB file. + + Parameters + ---------- + pdb_file : Path or str + Path to the PDB file. + chain : str or None + Chain ID or chain IDs (space-separated) of the protein. + method : {'CA', 'CB', 'minimum', 'CB_force'} + Method for defining the representative coordinates. + max_distance : float + Maximum distance (angstrom) to include. Pairs beyond this are not stored. + + Returns + ------- + Tuple[np.ndarray, np.ndarray, np.ndarray, int] + (contact_i, contact_j, distances, L). Both (i,j) and (j,i) stored. + """ + if max_distance <= 0: + raise ValueError("max_distance must be > 0") + structure, chain_selection = _parse_structure(pdb_file, chain) + if method == 'minimum': + return _sparse_minimum_distance(structure, chain_selection, max_distance) + coords = _get_residue_coords(structure, chain_selection, method) + return _coords_to_sparse(coords, max_distance) diff --git a/frustratometer/pdb/pdb.py b/frustratometer/pdb/pdb.py index 853e6e62..2e3e7499 100644 --- a/frustratometer/pdb/pdb.py +++ b/frustratometer/pdb/pdb.py @@ -1,9 +1,5 @@ from Bio.PDB import PDBParser,MMCIFParser -import prody -import scipy.spatial.distance as sdist -import pandas as pd import numpy as np -import itertools import os from pathlib import Path from typing import Union @@ -85,88 +81,6 @@ def get_sequence(pdb_file: str, return sequence - -def get_distance_matrix(pdb_file: Union[Path,str], - chain: str, - method: str = 'CB' - ) -> np.array: - """ - Calculate the distance matrix of the specified atoms in a PDB file. - - Parameters - ---------- - pdb_file: Path or str - The path to the PDB file. - chain: str - The chainID or chainIDs (space separated) of the protein. - method: str - The method to use for calculating the distance matrix. - Defaults to 'CB', which uses the CB atom for all residues except GLY, which uses the CA atom. - Options: - 'CA' for using only the CA atom, - 'minimum' for using the minimum distance between all atoms in each residue, - 'CB_force' computes a new coordinate for the CB atom based on the CA, C, and N atoms and uses CB distance even for glycine. - - Returns: - np.array: The distance matrix of the selected atoms. - - Raises: - IndexError: If the selection of atoms is empty. - ValueError: If the method is not recognized. - """ - - structure = prody.parsePDB(str(pdb_file)) - chain_selection = '' if chain is None else f' and chain {chain}' - - if method == 'CA': - coords = structure.select('protein and name CA' + chain_selection).getCoords() - elif method == 'CB': - coords = structure.select('(protein and (name CB) or (resname GLY and name CA))' + chain_selection).getCoords() - elif method == 'minimum': - selection = structure.select('protein' + chain_selection) - coords = selection.getCoords() - distance_matrix = sdist.squareform(sdist.pdist(coords)) - resids = selection.getResindices() - residues = pd.Series(resids).unique() - selections = np.array([resids == a for a in residues]) - dm = np.zeros((len(residues), len(residues))) - for i, j in itertools.combinations(range(len(residues)), 2): - d = distance_matrix[selections[i]][:, selections[j]].min() - dm[i, j] = d - dm[j, i] = d - return dm - elif method == 'CB_force': - sel_CA = structure.select('name CA') - sel_N = structure.select('name N') - sel_C = structure.select('name C') - - # Base vectors - vector_CA_C=sel_C.getCoords() - sel_CA.getCoords() - vector_CA_N=sel_N.getCoords() - sel_CA.getCoords() - - vector_CA_C/=np.linalg.norm(vector_CA_C,axis=1,keepdims=True) - vector_CA_N/=np.linalg.norm(vector_CA_N,axis=1,keepdims=True) - - #First Ortogonal vector - cross_CA_C_CA_N=np.cross(vector_CA_C,vector_CA_N) - cross_CA_C_CA_N/=np.linalg.norm(cross_CA_C_CA_N,axis=1,keepdims=True) - - #Second Ortogonal vector - cross_cross_CA_N=np.cross(cross_CA_C_CA_N,vector_CA_N) - cross_cross_CA_N/= np.linalg.norm(cross_cross_CA_N,axis=1,keepdims=True) - - #Precomputed CB coordinates - coords = -0.531020*vector_CA_N-1.206181*cross_CA_C_CA_N+0.789162*cross_cross_CA_N+sel_CA.getCoords() - else: - raise ValueError(f"Invalid method '{method}'. Accepted methods are 'CA', 'CB', 'minimum', and 'CB_force'.") - - if len(coords) == 0: - raise IndexError('Empty selection for distance map') - - distance_matrix = sdist.squareform(sdist.pdist(coords)) - return distance_matrix - - def full_to_filtered_aligned_mapping(aligned_sequence: str, filtered_aligned_sequence: str)->dict: diff --git a/tests/test_dca_frustratometer.py b/tests/test_dca_frustratometer.py index 05afd1ad..eaa63a06 100644 --- a/tests/test_dca_frustratometer.py +++ b/tests/test_dca_frustratometer.py @@ -173,7 +173,7 @@ def test_distance_matrix(): pdb_path = f'{data_path}/6JXX_A.pdb' chain_id = 'A' - distance_matrix = frustratometer.pdb.get_distance_matrix(pdb_path, chain_id, method='CB') + distance_matrix = frustratometer.pdb.get_full_distance_matrix(pdb_path, chain_id, method='CB') original_distance_matrix=np.loadtxt(f"{data_path}/6JXX_A_CB_CB_Distance_Map.txt") assert (original_distance_matrix==distance_matrix).all() @@ -225,7 +225,7 @@ def test_functional_compute_DCA_native_energy(): expected_energy = -61.5248 sequence = frustratometer.pdb.get_sequence(pdb_path, chain_id) - distance_matrix = frustratometer.pdb.get_distance_matrix(pdb_path, chain_id, method='minimum') + distance_matrix = frustratometer.pdb.get_full_distance_matrix(pdb_path, chain_id, method='minimum') potts_model = frustratometer.dca.matlab.load_potts_model(potts_model_path) mask = frustratometer.frustration.compute_mask(distance_matrix, maximum_contact_distance=4, minimum_sequence_separation=0) energy = frustratometer.frustration.compute_native_energy(sequence, potts_model, mask) @@ -401,7 +401,7 @@ def test_compute_singleresidue_DCA_decoy_energy(): pos_x = 30 distance_cutoff = 4 sequence_cutoff = 0 - distance_matrix = frustratometer.pdb.get_distance_matrix('examples/data/1cyo.pdb', 'A') + distance_matrix = frustratometer.pdb.get_full_distance_matrix('examples/data/1cyo.pdb', 'A') potts_model = frustratometer.dca.matlab.load_potts_model('examples/data/PottsModel1cyoA.mat') seq = frustratometer.pdb.get_sequence('examples/data/1cyo.pdb', 'A') mask = frustratometer.frustration.compute_mask(distance_matrix, distance_cutoff, sequence_cutoff) @@ -421,7 +421,7 @@ def test_compute_mutational_DCA_decoy_energy(): pos_y = 69 distance_cutoff = 4 sequence_cutoff = 0 - distance_matrix = frustratometer.pdb.get_distance_matrix('examples/data/1cyo.pdb', 'A') + distance_matrix = frustratometer.pdb.get_full_distance_matrix('examples/data/1cyo.pdb', 'A') potts_model = frustratometer.dca.matlab.load_potts_model('examples/data/PottsModel1cyoA.mat') seq = frustratometer.pdb.get_sequence('examples/data/1cyo.pdb', 'A') mask = frustratometer.frustration.compute_mask(distance_matrix, distance_cutoff, sequence_cutoff) diff --git a/tests/test_sparse_distance.py b/tests/test_sparse_distance.py new file mode 100644 index 00000000..1b62eeb4 --- /dev/null +++ b/tests/test_sparse_distance.py @@ -0,0 +1,59 @@ +"""Tests for distance matrix computation (full and sparse).""" +import numpy as np +import pytest +from pathlib import Path +from frustratometer.pdb.distance import get_full_distance_matrix, get_sparse_distance_matrix + +PDB_FILE = Path(__file__).parent / "data" / "6u5e.pdb" +CHAIN = "A" +MAX_DISTANCE = 15.0 + + +def test_full_matches_known_reference(): + """Full CB matrix must reproduce the saved reference exactly.""" + ref_path = Path(__file__).parent / "data" / "6JXX_A_CB_CB_Distance_Map.txt" + pdb_path = Path(__file__).parent / "data" / "6JXX_A.pdb" + reference = np.loadtxt(ref_path) + computed = get_full_distance_matrix(pdb_path, "A", method="CB") + np.testing.assert_array_equal(computed, reference) + + +@pytest.mark.parametrize("method", ["CA", "CB", "minimum", "CB_force"]) +def test_sparse_is_lossless_subset_of_full(method): + """Reconstructing a dense matrix from sparse entries must equal + the full matrix everywhere within the cutoff (and zero elsewhere).""" + full = get_full_distance_matrix(PDB_FILE, CHAIN, method=method) + ci, cj, d, L = get_sparse_distance_matrix(PDB_FILE, CHAIN, method, MAX_DISTANCE) + assert L == full.shape[0] + + # Reconstruct dense from sparse + reconstructed = np.zeros((L, L)) + reconstructed[ci, cj] = d + + # Where full <= cutoff and off-diagonal, reconstructed must match + mask = (full > 0) & (full <= MAX_DISTANCE) + np.testing.assert_allclose(reconstructed[mask], full[mask], atol=1e-10) + # Where full > cutoff, reconstructed must be zero (not stored) + np.testing.assert_array_equal(reconstructed[~mask], 0) + + +def test_sparse_cutoff_respected(): + """Tighter cutoff produces fewer entries, all within bound.""" + ci_w, _, d_wide, _ = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 15.0) + ci_n, _, d_narrow, _ = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 8.0) + assert len(d_narrow) < len(d_wide) + assert d_narrow.max() <= 8.0 + assert d_wide.max() <= 15.0 + assert d_wide.max() > 8.0 + + +def test_structure_sparse_flag(): + """sparse=True populates sparse_distance_data; False leaves it None.""" + import frustratometer + s_on = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=True) + assert s_on.sparse_distance_data is not None + ci, cj, d, L = s_on.sparse_distance_data + assert L == len(s_on.sequence) + + s_off = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=False) + assert s_off.sparse_distance_data is None From 43524bee67aa3aa56dd600ddfb6d856d53753810 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 7 Apr 2026 00:14:18 -0500 Subject: [PATCH 04/28] renames full to dense --- frustratometer/classes/DCA.py | 2 +- frustratometer/classes/Structure.py | 4 ++-- frustratometer/pdb/__init__.py | 6 +++--- frustratometer/pdb/distance.py | 2 +- tests/test_dca_frustratometer.py | 8 ++++---- tests/test_sparse_distance.py | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/frustratometer/classes/DCA.py b/frustratometer/classes/DCA.py index 06767229..3d7cc7d9 100644 --- a/frustratometer/classes/DCA.py +++ b/frustratometer/classes/DCA.py @@ -526,7 +526,7 @@ def distance_matrix_method(self): @distance_matrix_method.setter def distance_matrix_method(self, value): - self.distance_matrix = pdb.get_full_distance_matrix(self._pdb_file, self._chain, value) + self.distance_matrix = pdb.get_dense_distance_matrix(self._pdb_file, self._chain, value) self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff) self._distance_matrix_method = value self._native_energy = None diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index d06c7ece..249bc90a 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -195,8 +195,8 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self.structure=prody.parseMMCIF(str(self.pdb_file),chain=self.chain).select(f"protein and {self.seq_selection}") self.sequence=pdb.get_sequence(self.pdb_file,self.chain) - self.distance_matrix=pdb.get_full_distance_matrix(pdb_file=self.pdb_file,chain=self.chain, - method=self.distance_matrix_method) + self.distance_matrix=pdb.get_dense_distance_matrix(pdb_file=self.pdb_file,chain=self.chain, + method=self.distance_matrix_method) self.full_pdb_distance_matrix=self.distance_matrix # Compute sparse distance data if requested diff --git a/frustratometer/pdb/__init__.py b/frustratometer/pdb/__init__.py index fdf95946..956b4d1f 100644 --- a/frustratometer/pdb/__init__.py +++ b/frustratometer/pdb/__init__.py @@ -5,7 +5,7 @@ If you want to extract the structure's sequence, use the "get_sequence" function. -If you want to extract the distance matrix of the structure's contacts, use the "get_full_distance_matrix" function. +If you want to extract the distance matrix of the structure's contacts, use the "get_dense_distance_matrix" function. If you want to map the full sequence residue positions to the aligned sequence residue positions (may be needed if applying a distance threshold in DCA-related calculations), use the "full_to_filtered_aligned_mapping" function. @@ -13,7 +13,7 @@ """ from .pdb import * -from .distance import get_full_distance_matrix, get_sparse_distance_matrix +from .distance import get_dense_distance_matrix, get_sparse_distance_matrix try: from .fix import repair_pdb, repair_pdbs except ImportError as e: @@ -34,4 +34,4 @@ def warn_pdbfixer_not_installed(): else: raise e -__all__ = ['download', 'get_sequence', 'get_full_distance_matrix', 'get_sparse_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs'] \ No newline at end of file +__all__ = ['download', 'get_sequence', 'get_dense_distance_matrix', 'get_sparse_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs'] \ No newline at end of file diff --git a/frustratometer/pdb/distance.py b/frustratometer/pdb/distance.py index 2631e265..fbe562c4 100644 --- a/frustratometer/pdb/distance.py +++ b/frustratometer/pdb/distance.py @@ -173,7 +173,7 @@ def _coords_to_sparse(coords, max_distance): # Public API # --------------------------------------------------------------------------- -def get_full_distance_matrix( +def get_dense_distance_matrix( pdb_file: Union[Path, str], chain: Optional[str], method: str = 'CB', diff --git a/tests/test_dca_frustratometer.py b/tests/test_dca_frustratometer.py index eaa63a06..2d7d2d54 100644 --- a/tests/test_dca_frustratometer.py +++ b/tests/test_dca_frustratometer.py @@ -173,7 +173,7 @@ def test_distance_matrix(): pdb_path = f'{data_path}/6JXX_A.pdb' chain_id = 'A' - distance_matrix = frustratometer.pdb.get_full_distance_matrix(pdb_path, chain_id, method='CB') + distance_matrix = frustratometer.pdb.get_dense_distance_matrix(pdb_path, chain_id, method='CB') original_distance_matrix=np.loadtxt(f"{data_path}/6JXX_A_CB_CB_Distance_Map.txt") assert (original_distance_matrix==distance_matrix).all() @@ -225,7 +225,7 @@ def test_functional_compute_DCA_native_energy(): expected_energy = -61.5248 sequence = frustratometer.pdb.get_sequence(pdb_path, chain_id) - distance_matrix = frustratometer.pdb.get_full_distance_matrix(pdb_path, chain_id, method='minimum') + distance_matrix = frustratometer.pdb.get_dense_distance_matrix(pdb_path, chain_id, method='minimum') potts_model = frustratometer.dca.matlab.load_potts_model(potts_model_path) mask = frustratometer.frustration.compute_mask(distance_matrix, maximum_contact_distance=4, minimum_sequence_separation=0) energy = frustratometer.frustration.compute_native_energy(sequence, potts_model, mask) @@ -401,7 +401,7 @@ def test_compute_singleresidue_DCA_decoy_energy(): pos_x = 30 distance_cutoff = 4 sequence_cutoff = 0 - distance_matrix = frustratometer.pdb.get_full_distance_matrix('examples/data/1cyo.pdb', 'A') + distance_matrix = frustratometer.pdb.get_dense_distance_matrix('examples/data/1cyo.pdb', 'A') potts_model = frustratometer.dca.matlab.load_potts_model('examples/data/PottsModel1cyoA.mat') seq = frustratometer.pdb.get_sequence('examples/data/1cyo.pdb', 'A') mask = frustratometer.frustration.compute_mask(distance_matrix, distance_cutoff, sequence_cutoff) @@ -421,7 +421,7 @@ def test_compute_mutational_DCA_decoy_energy(): pos_y = 69 distance_cutoff = 4 sequence_cutoff = 0 - distance_matrix = frustratometer.pdb.get_full_distance_matrix('examples/data/1cyo.pdb', 'A') + distance_matrix = frustratometer.pdb.get_dense_distance_matrix('examples/data/1cyo.pdb', 'A') potts_model = frustratometer.dca.matlab.load_potts_model('examples/data/PottsModel1cyoA.mat') seq = frustratometer.pdb.get_sequence('examples/data/1cyo.pdb', 'A') mask = frustratometer.frustration.compute_mask(distance_matrix, distance_cutoff, sequence_cutoff) diff --git a/tests/test_sparse_distance.py b/tests/test_sparse_distance.py index 1b62eeb4..003220dd 100644 --- a/tests/test_sparse_distance.py +++ b/tests/test_sparse_distance.py @@ -2,7 +2,7 @@ import numpy as np import pytest from pathlib import Path -from frustratometer.pdb.distance import get_full_distance_matrix, get_sparse_distance_matrix +from frustratometer.pdb.distance import get_dense_distance_matrix, get_sparse_distance_matrix PDB_FILE = Path(__file__).parent / "data" / "6u5e.pdb" CHAIN = "A" @@ -14,7 +14,7 @@ def test_full_matches_known_reference(): ref_path = Path(__file__).parent / "data" / "6JXX_A_CB_CB_Distance_Map.txt" pdb_path = Path(__file__).parent / "data" / "6JXX_A.pdb" reference = np.loadtxt(ref_path) - computed = get_full_distance_matrix(pdb_path, "A", method="CB") + computed = get_dense_distance_matrix(pdb_path, "A", method="CB") np.testing.assert_array_equal(computed, reference) @@ -22,7 +22,7 @@ def test_full_matches_known_reference(): def test_sparse_is_lossless_subset_of_full(method): """Reconstructing a dense matrix from sparse entries must equal the full matrix everywhere within the cutoff (and zero elsewhere).""" - full = get_full_distance_matrix(PDB_FILE, CHAIN, method=method) + full = get_dense_distance_matrix(PDB_FILE, CHAIN, method=method) ci, cj, d, L = get_sparse_distance_matrix(PDB_FILE, CHAIN, method, MAX_DISTANCE) assert L == full.shape[0] From 66e84f28a0b0a8e531d933fb9cbc47b1148462d4 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 7 Apr 2026 00:18:41 -0500 Subject: [PATCH 05/28] Adds sparse potts model --- frustratometer/frustration/__init__.py | 6 +- frustratometer/frustration/frustration.py | 155 +++++++++++++++++++++- tests/test_sparse_potts.py | 92 +++++++++++++ 3 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 tests/test_sparse_potts.py diff --git a/frustratometer/frustration/__init__.py b/frustratometer/frustration/__init__.py index ef9e9901..a5400d54 100644 --- a/frustratometer/frustration/__init__.py +++ b/frustratometer/frustration/__init__.py @@ -20,4 +20,8 @@ 'compute_decoy_h_J', 'compute_native_fragment_energy_from_h_j', 'compute_decoy_fragment_energy_from_h_j', - 'compute_energy_sliding_window'] + 'compute_energy_sliding_window', + 'compute_mask_sparse', + 'potts_model_dense_to_sparse', + 'potts_model_sparse_to_dense', + 'build_contact_lookup'] diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index 948911e0..1c9dc70b 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -1601,4 +1601,157 @@ def compute_energy_sliding_window(seq: str, 'frustration': frustration_sw } - return results \ No newline at end of file + return results + + +def compute_mask_sparse(contact_i: np.ndarray, + contact_j: np.ndarray, + contact_distances: np.ndarray, + L: int, + maximum_contact_distance: Union[float, None] = None, + minimum_sequence_separation: Union[int, None] = None): + """ + Compute a sparse mask from sparse distance data. + + Parameters + ---------- + contact_i : np.ndarray (N,) + Row indices of distance pairs (from sparse distance matrix). + contact_j : np.ndarray (N,) + Column indices of distance pairs. + contact_distances : np.ndarray (N,) + Distances for each (i, j) pair. + L : int + Sequence length (number of residues). + maximum_contact_distance : float, optional + Include pair if distance <= this value. If None, no distance filtering. + minimum_sequence_separation : int, optional + Include pair if |i - j| >= this value. If None, no sequence separation filtering. + + Returns + ------- + mask_i : np.ndarray + Row indices of pairs that pass the mask criteria. + mask_j : np.ndarray + Column indices of pairs that pass the mask criteria. + """ + keep = np.ones(len(contact_i), dtype=bool) + + if maximum_contact_distance is not None: + keep &= contact_distances <= maximum_contact_distance + + if minimum_sequence_separation is not None: + keep &= np.abs(contact_i.astype(np.int64) - contact_j.astype(np.int64)) >= minimum_sequence_separation + + return contact_i[keep], contact_j[keep] + + +def potts_model_dense_to_sparse(potts_model: dict, mask: np.ndarray) -> dict: + """ + Convert a dense Potts model to sparse format, keeping only couplings at masked positions. + + Both (i,j) and (j,i) entries are stored to preserve the existing ``sum / 2`` + energy summation pattern. + + Parameters + ---------- + potts_model : dict + Dense Potts model with 'h' (L, Q) and 'J' (L, L, Q, Q). + mask : np.ndarray + Boolean mask (L, L). True means the pair is a contact. + + Returns + ------- + sparse_potts_model : dict + Dictionary with keys: + - 'h': np.ndarray (L, Q) — unchanged + - 'J': np.ndarray (N_contacts, Q, Q) — couplings at contact positions + - 'contact_i': np.ndarray (N_contacts,) — row indices + - 'contact_j': np.ndarray (N_contacts,) — column indices + - 'L': int — sequence length + """ + contact_i, contact_j = np.where(mask) + J_sparse = potts_model['J'][contact_i, contact_j, :, :] + return { + 'h': potts_model['h'], + 'J': J_sparse, + 'contact_i': contact_i.astype(np.intp), + 'contact_j': contact_j.astype(np.intp), + 'L': potts_model['h'].shape[0], + } + + +def potts_model_sparse_to_dense(sparse_potts_model: dict) -> dict: + """ + Convert a sparse Potts model back to dense format. + + Couplings at positions not stored in the sparse model are set to zero. + + Parameters + ---------- + sparse_potts_model : dict + Sparse Potts model (see ``potts_model_dense_to_sparse``). + + Returns + ------- + potts_model : dict + Dense Potts model with 'h' (L, Q) and 'J' (L, L, Q, Q). + """ + L = sparse_potts_model['L'] + Q = sparse_potts_model['h'].shape[1] + J = np.zeros((L, L, Q, Q), dtype=sparse_potts_model['J'].dtype) + J[sparse_potts_model['contact_i'], sparse_potts_model['contact_j'], :, :] = sparse_potts_model['J'] + return { + 'h': sparse_potts_model['h'], + 'J': J, + } + + +def build_contact_lookup(contact_i: np.ndarray, contact_j: np.ndarray, L: int) -> tuple: + """ + Build CSR-like flat arrays mapping each position to its contacts. + + For position ``p``, contacts are at indices + ``lookup_data[lookup_offsets[p]:lookup_offsets[p+1]]`` in the sparse J array, + and the partner positions are + ``lookup_partners[lookup_offsets[p]:lookup_offsets[p+1]]``. + + Parameters + ---------- + contact_i : np.ndarray (N_contacts,) + Row indices of contacts. + contact_j : np.ndarray (N_contacts,) + Column indices of contacts. + L : int + Sequence length. + + Returns + ------- + lookup_offsets : np.ndarray (L+1,) + CSR-style offset array. + lookup_partners : np.ndarray (N_contacts,) + Partner position for each contact entry. + lookup_indices : np.ndarray (N_contacts,) + Index into sparse J array for each contact entry. + """ + N = len(contact_i) + # Count contacts per position (using contact_i as the "row") + counts = np.zeros(L, dtype=np.intp) + for k in range(N): + counts[contact_i[k]] += 1 + + lookup_offsets = np.zeros(L + 1, dtype=np.intp) + np.cumsum(counts, out=lookup_offsets[1:]) + + # Fill partner and index arrays + lookup_partners = np.empty(N, dtype=np.intp) + lookup_indices = np.empty(N, dtype=np.intp) + current = lookup_offsets[:-1].copy() + for k in range(N): + p = contact_i[k] + pos = current[p] + lookup_partners[pos] = contact_j[k] + lookup_indices[pos] = k + current[p] += 1 + + return lookup_offsets, lookup_partners, lookup_indices \ No newline at end of file diff --git a/tests/test_sparse_potts.py b/tests/test_sparse_potts.py new file mode 100644 index 00000000..19d4b740 --- /dev/null +++ b/tests/test_sparse_potts.py @@ -0,0 +1,92 @@ +"""Tests for sparse Potts model infrastructure (mask, convert, lookup).""" +import numpy as np +import pytest +from frustratometer.frustration.frustration import ( + compute_mask, + compute_mask_sparse, + potts_model_dense_to_sparse, + potts_model_sparse_to_dense, + build_contact_lookup, +) + + +@pytest.fixture +def small_system(): + """10-residue system with a random distance matrix and Potts model.""" + rng = np.random.default_rng(42) + L, Q = 10, 21 + + # Symmetric distance matrix with zero diagonal + dm = rng.uniform(3, 20, size=(L, L)) + dm = (dm + dm.T) / 2 + np.fill_diagonal(dm, 0) + + # Sparse distance representation (both directions, like cKDTree output) + ii, jj = np.triu_indices(L, k=1) + contact_i = np.concatenate([ii, jj]).astype(np.intp) + contact_j = np.concatenate([jj, ii]).astype(np.intp) + contact_d = np.concatenate([dm[ii, jj], dm[ii, jj]]) + + # Symmetric dense Potts model + potts_model = { + 'h': rng.standard_normal((L, Q)), + 'J': rng.standard_normal((L, L, Q, Q)), + } + potts_model['J'] = (potts_model['J'] + potts_model['J'].transpose(1, 0, 3, 2)) / 2 + + return L, Q, dm, contact_i, contact_j, contact_d, potts_model + + + +@pytest.mark.parametrize("max_dist,min_sep", [ + (10.0, 3), + (15.0, None), +]) +def test_sparse_mask_matches_dense(small_system, max_dist, min_sep): + """Sparse mask must select the same off-diagonal (i,j) pairs as the dense mask.""" + L, Q, dm, ci, cj, cd, _ = small_system + + dense_mask = compute_mask(dm, max_dist, min_sep) + sparse_i, sparse_j = compute_mask_sparse(ci, cj, cd, L, max_dist, min_sep) + + reconstructed = np.zeros((L, L), dtype=bool) + reconstructed[sparse_i, sparse_j] = True + + off_diag = ~np.eye(L, dtype=bool) + np.testing.assert_array_equal(reconstructed[off_diag], dense_mask[off_diag]) + + +def test_sparse_potts_roundtrip_and_lookup(small_system): + """dense→sparse→dense recovers J at contacts; lookup indexes them correctly.""" + L, Q, dm, _, _, _, potts_model = small_system + + mask = compute_mask(dm, maximum_contact_distance=10.0, minimum_sequence_separation=3) + sparse_pm = potts_model_dense_to_sparse(potts_model, mask) + recovered = potts_model_sparse_to_dense(sparse_pm) + + # h unchanged + np.testing.assert_array_equal(recovered['h'], potts_model['h']) + + # J matches at masked positions, zero elsewhere + ci, cj = np.where(mask) + np.testing.assert_allclose(recovered['J'][ci, cj, :, :], potts_model['J'][ci, cj, :, :]) + np.testing.assert_array_equal(recovered['J'][~mask, :, :], 0) + + +def test_contact_lookup(small_system): + """Lookup must cover every contact and point back correctly.""" + L, _, dm, _, _, _, potts_model = small_system + + mask = compute_mask(dm, maximum_contact_distance=10.0, minimum_sequence_separation=3) + sparse_pm = potts_model_dense_to_sparse(potts_model, mask) + offsets, partners, indices = build_contact_lookup(sparse_pm['contact_i'], sparse_pm['contact_j'], L) + + recovered_pairs = set() + for p in range(L): + for k in range(offsets[p], offsets[p + 1]): + recovered_pairs.add((p, partners[k])) + assert sparse_pm['contact_i'][indices[k]] == p + assert sparse_pm['contact_j'][indices[k]] == partners[k] + + original_pairs = set(zip(sparse_pm['contact_i'].tolist(), sparse_pm['contact_j'].tolist())) + assert recovered_pairs == original_pairs From fdf8593c700ca062d79559c9c04349d43c4dec5c Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 7 Apr 2026 00:47:12 -0500 Subject: [PATCH 06/28] Adds chain breaks to support correct sequence separation masking. --- frustratometer/classes/AWSEM.py | 11 +++--- frustratometer/classes/DCA.py | 22 +++++++----- frustratometer/classes/Structure.py | 6 ++++ frustratometer/frustration/frustration.py | 30 ++++++++++++---- tests/test_sparse_potts.py | 42 +++++++++++++++++++---- tests/test_structure.py | 12 +++++++ 6 files changed, 97 insertions(+), 26 deletions(-) diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index a25290c7..eb7584fb 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -114,6 +114,7 @@ def __init__(self, self.init_index_shift=pdb_structure.init_index_shift self.distance_matrix=pdb_structure.distance_matrix self.full_pdb_distance_matrix=pdb_structure.full_pdb_distance_matrix + self.chain_breaks=pdb_structure.chain_breaks selection_CB = self.structure.select('name CB or (resname GLY IGL and name CA)') resid = selection_CB.getResindices() @@ -127,10 +128,12 @@ def __init__(self, selected_matrix=self.distance_matrix sequence_mask_rho = frustration.compute_mask(selected_matrix, maximum_contact_distance=None, - minimum_sequence_separation = p.min_sequence_separation_rho) + minimum_sequence_separation = p.min_sequence_separation_rho, + chain_breaks=self.chain_breaks) sequence_mask_contact = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=p.distance_cutoff_contact, - minimum_sequence_separation = p.min_sequence_separation_contact) + minimum_sequence_separation = p.min_sequence_separation_contact, + chain_breaks=self.chain_breaks) self._decoy_fluctuation = {} self.minimally_frustrated_threshold=.78 @@ -214,7 +217,7 @@ def __init__(self, self.distance_cutoff=None - electrostatics_mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=None, minimum_sequence_separation=p.min_sequence_separation_electrostatics) + electrostatics_mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=None, minimum_sequence_separation=p.min_sequence_separation_electrostatics, chain_breaks=self.chain_breaks) # ['A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V'] charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) charges2 = charges[:,np.newaxis]*charges[np.newaxis,:] @@ -232,7 +235,7 @@ def __init__(self, else: self.sequence_cutoff=p.min_sequence_separation_contact self.distance_cutoff=p.distance_cutoff_contact - self.mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=self.distance_cutoff, minimum_sequence_separation = self.sequence_cutoff) + self.mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=self.distance_cutoff, minimum_sequence_separation = self.sequence_cutoff, chain_breaks=self.chain_breaks) self.contact_energy = contact_energy diff --git a/frustratometer/classes/DCA.py b/frustratometer/classes/DCA.py index 3d7cc7d9..3122bb08 100644 --- a/frustratometer/classes/DCA.py +++ b/frustratometer/classes/DCA.py @@ -147,13 +147,14 @@ def from_potts_model_file(cls,pdb_structure: object, self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix self.distance_matrix=self.mapped_distance_matrix + self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) if self.distance_cutoff==None: example_matrix=np.ones((len(self.filtered_aligned_sequence),len(self.filtered_aligned_sequence))) - self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) else: - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) self.minimally_frustrated_threshold=1 @@ -225,12 +226,13 @@ def from_pottsmodel(cls,pdb_structure : object, self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix self.distance_matrix=self.mapped_distance_matrix + self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) if self.distance_cutoff==None: example_matrix=np.ones((len(self.filtered_aligned_sequence),len(self.filtered_aligned_sequence))) - self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) else: - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) self.minimally_frustrated_threshold=1 @@ -300,7 +302,8 @@ def from_pfam_alignment(cls,pdb_structure : object, self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix self.distance_matrix=self.mapped_distance_matrix - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) + self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) self.minimally_frustrated_threshold=1 @@ -376,7 +379,8 @@ def from_hmmer_alignment(cls,pdb_structure : object, self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix self.distance_matrix=self.mapped_distance_matrix - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) + self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) self.minimally_frustrated_threshold=1 @@ -504,7 +508,7 @@ def sequence_cutoff(self): @sequence_cutoff.setter def sequence_cutoff(self, value): - self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._sequence_cutoff = value self._native_energy = None self._decoy_fluctuation = {} @@ -515,7 +519,7 @@ def distance_cutoff(self): @distance_cutoff.setter def distance_cutoff(self, value): - self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._distance_cutoff = value self._native_energy = None self._decoy_fluctuation = {} @@ -527,7 +531,7 @@ def distance_matrix_method(self): @distance_matrix_method.setter def distance_matrix_method(self, value): self.distance_matrix = pdb.get_dense_distance_matrix(self._pdb_file, self._chain, value) - self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff) + self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._distance_matrix_method = value self._native_energy = None self._decoy_fluctuation = {} diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index 249bc90a..c969ea40 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -209,6 +209,12 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self.z_coordinates=self.structure.select('((name CB) or (resname GLY and name CA))').getCoords() + # Detect chain breaks from per-residue chain IDs + ca_sel = self.structure.select('name CA') + chids = ca_sel.getChids() + breaks = np.where(chids[:-1] != chids[1:])[0] + 1 + self.chain_breaks = breaks.tolist() if len(breaks) > 0 else None + if self.seq_selection!=None: self.distance_matrix=self.distance_matrix[self.init_index_shift:self.fin_index_shift, self.init_index_shift:self.fin_index_shift] diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index 1c9dc70b..bc52aec0 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -26,7 +26,8 @@ def compute_mask(distance_matrix: np.array, maximum_contact_distance: Union[float, None] = None, - minimum_sequence_separation: Union[int, None] = None) -> np.array: + minimum_sequence_separation: Union[int, None] = None, + chain_breaks: Union[list, None] = None) -> np.array: """ Computes a 2D Boolean mask (L, L) for pairwise interactions from a given distance matrix using a distance cutoff and/or a minimum sequence-separation cutoff. Both cutoffs are inclusive. True indicates that the residue pair meets the criteria. @@ -42,6 +43,11 @@ def compute_mask(distance_matrix: np.array, minimum_sequence_separation : int, optional A minimum sequence separation threshold. Include i,j if |i-j| >= minimum_sequence_separation. If None, no sequence separation is applied . Default is None. + chain_breaks : list of int, optional + Indices where new chains begin (excluding the implicit 0). For example, [50, 80] + means three chains: residues 0-49, 50-79, 80-end. Cross-chain pairs always satisfy + the minimum sequence separation, since they are not bonded in sequence. + If None, all residues are treated as a single chain. Default is None. Returns ------- @@ -58,13 +64,15 @@ def compute_mask(distance_matrix: np.array, [[False True False] [ True False True] [False True False]] - - .. todo:: Add chain information for sequence separation """ seq_len = len(distance_matrix) mask = np.ones([seq_len, seq_len]) if minimum_sequence_separation is not None: - sequence_distance = sdist.squareform(sdist.pdist(np.arange(seq_len)[:, np.newaxis])) + positions = np.arange(seq_len, dtype=np.float64) + if chain_breaks is not None: + for brk in chain_breaks: + positions[brk:] += minimum_sequence_separation + sequence_distance = sdist.squareform(sdist.pdist(positions[:, np.newaxis])) mask *= sequence_distance >= minimum_sequence_separation if maximum_contact_distance is not None: mask *= distance_matrix <= maximum_contact_distance @@ -1609,7 +1617,8 @@ def compute_mask_sparse(contact_i: np.ndarray, contact_distances: np.ndarray, L: int, maximum_contact_distance: Union[float, None] = None, - minimum_sequence_separation: Union[int, None] = None): + minimum_sequence_separation: Union[int, None] = None, + chain_breaks: Union[list, None] = None): """ Compute a sparse mask from sparse distance data. @@ -1627,6 +1636,9 @@ def compute_mask_sparse(contact_i: np.ndarray, Include pair if distance <= this value. If None, no distance filtering. minimum_sequence_separation : int, optional Include pair if |i - j| >= this value. If None, no sequence separation filtering. + chain_breaks : list of int, optional + Indices where new chains begin (excluding the implicit 0). Cross-chain pairs + always satisfy the minimum sequence separation. Default is None. Returns ------- @@ -1641,7 +1653,13 @@ def compute_mask_sparse(contact_i: np.ndarray, keep &= contact_distances <= maximum_contact_distance if minimum_sequence_separation is not None: - keep &= np.abs(contact_i.astype(np.int64) - contact_j.astype(np.int64)) >= minimum_sequence_separation + pos_i = contact_i.astype(np.float64) + pos_j = contact_j.astype(np.float64) + if chain_breaks is not None: + for brk in chain_breaks: + pos_i = np.where(contact_i >= brk, pos_i + minimum_sequence_separation, pos_i) + pos_j = np.where(contact_j >= brk, pos_j + minimum_sequence_separation, pos_j) + keep &= np.abs(pos_i - pos_j) >= minimum_sequence_separation return contact_i[keep], contact_j[keep] diff --git a/tests/test_sparse_potts.py b/tests/test_sparse_potts.py index 19d4b740..ccd353c1 100644 --- a/tests/test_sparse_potts.py +++ b/tests/test_sparse_potts.py @@ -38,16 +38,18 @@ def small_system(): -@pytest.mark.parametrize("max_dist,min_sep", [ - (10.0, 3), - (15.0, None), +@pytest.mark.parametrize("max_dist,min_sep,chain_breaks", [ + (10.0, 3, None), + (15.0, None, None), + (10.0, 3, [5]), + (None, 3, [3, 6]), ]) -def test_sparse_mask_matches_dense(small_system, max_dist, min_sep): - """Sparse mask must select the same off-diagonal (i,j) pairs as the dense mask.""" +def test_sparse_mask_matches_dense(small_system, max_dist, min_sep, chain_breaks): + """Dense and sparse masks must agree; cross-chain pairs always pass separation.""" L, Q, dm, ci, cj, cd, _ = small_system - dense_mask = compute_mask(dm, max_dist, min_sep) - sparse_i, sparse_j = compute_mask_sparse(ci, cj, cd, L, max_dist, min_sep) + dense_mask = compute_mask(dm, max_dist, min_sep, chain_breaks=chain_breaks) + sparse_i, sparse_j = compute_mask_sparse(ci, cj, cd, L, max_dist, min_sep, chain_breaks=chain_breaks) reconstructed = np.zeros((L, L), dtype=bool) reconstructed[sparse_i, sparse_j] = True @@ -55,6 +57,17 @@ def test_sparse_mask_matches_dense(small_system, max_dist, min_sep): off_diag = ~np.eye(L, dtype=bool) np.testing.assert_array_equal(reconstructed[off_diag], dense_mask[off_diag]) + # When chain_breaks + min_sep are active, cross-chain pairs that pass the + # distance filter must always be included (they are not bonded in sequence). + if chain_breaks is not None and min_sep is not None: + boundaries = [0] + chain_breaks + [L] + for c1 in range(len(boundaries) - 1): + for c2 in range(c1 + 1, len(boundaries) - 1): + i = boundaries[c1 + 1] - 1 # last residue of chain c1 + j = boundaries[c2] # first residue of chain c2 + if max_dist is None or dm[i, j] <= max_dist: + assert dense_mask[i, j] + def test_sparse_potts_roundtrip_and_lookup(small_system): """dense→sparse→dense recovers J at contacts; lookup indexes them correctly.""" @@ -90,3 +103,18 @@ def test_contact_lookup(small_system): original_pairs = set(zip(sparse_pm['contact_i'].tolist(), sparse_pm['contact_j'].tolist())) assert recovered_pairs == original_pairs + + +def test_structure_detects_chain_breaks(): + """Structure must detect chain boundaries from a multi-chain CIF file.""" + from pathlib import Path + from frustratometer.classes.Structure import Structure + + cif_path = Path(__file__).parent / "data" / "5msm.cif" + if not cif_path.exists(): + pytest.skip("5msm.cif not available") + + s = Structure(cif_path, chain=None) + # 5msm has 6 chains (A,B,C,D,E,F) → 5 break points + assert s.chain_breaks is not None + assert len(s.chain_breaks) == 5 diff --git a/tests/test_structure.py b/tests/test_structure.py index 163c5c55..2764a5de 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -104,3 +104,15 @@ def test_pdbfixer_leaks_without_isolation(tmp_path): f"Memory only grew {growth_mb:.0f} MB. PDBFixer leak may have been fixed. " f"Consider removing multiprocessing isolation in fix.py." ) + +def test_structure_detects_chain_breaks(): + """Structure must detect chain boundaries from a multi-chain CIF file.""" + + cif_path = Path(__file__).parent / "data" / "5msm.cif" + if not cif_path.exists(): + pytest.skip("5msm.cif not available") + + s = frustratometer.Structure(cif_path, chain=None) + # 5msm has 6 chains (A,B,C,D,E,F) → 5 break points + assert s.chain_breaks is not None + assert len(s.chain_breaks) == 5 \ No newline at end of file From 3fabff7d2063e856254ba7add6a9730bab40dd9e Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 7 Apr 2026 01:27:23 -0500 Subject: [PATCH 07/28] Adds computing energy from sparse matrices --- frustratometer/classes/Frustratometer.py | 47 ++++++++- frustratometer/frustration/__init__.py | 5 +- frustratometer/frustration/frustration.py | 122 ++++++++++++++++++++++ tests/test_awsem_frustratometer.py | 46 ++++++++ 4 files changed, 214 insertions(+), 6 deletions(-) diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index 962050f7..b760f5ec 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -41,6 +41,21 @@ class Frustratometer: # self._native_energy = None # self._decoy_fluctuation = {} + def _ensure_dense_potts_model(self): + """Reconstruct dense J from sparse potts model if needed.""" + if self._potts_model.get('J') is None and getattr(self, 'sparse_potts_model', None) is not None: + self._potts_model['J'] = frustration.potts_model_sparse_to_dense(self.sparse_potts_model)['J'] + + @property + def potts_model(self): + """Access the Potts model dict with auto-reconstruction of J from sparse if needed.""" + self._ensure_dense_potts_model() + return self._potts_model + + @potts_model.setter + def potts_model(self, value): + self._potts_model = value + def native_energy(self,sequence:str = None,ignore_couplings_of_gaps:bool=False,ignore_fields_of_gaps:bool = False) -> float: """ Calculates the native energy of the protein sequence. @@ -61,9 +76,14 @@ def native_energy(self,sequence:str = None,ignore_couplings_of_gaps:bool=False,i if sequence is None: sequence=self.sequence else: + if getattr(self, 'sparse_potts_model', None) is not None: + return frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) return frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) if not self._native_energy: - self._native_energy=frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) + if getattr(self, 'sparse_potts_model', None) is not None: + self._native_energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) + else: + self._native_energy=frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) energy_value=self._native_energy return energy_value @@ -89,7 +109,10 @@ def sequences_energies(self, sequences:np.array, split_couplings_and_fields:bool output (if split_couplings_and_fields==True): np.array Array containing computed fields and couplings energies of the protein sequences. """ - output=frustration.compute_sequences_energy(sequences, self.potts_model, self.mask, split_couplings_and_fields) + if getattr(self, 'sparse_potts_model', None) is not None: + output=frustration.compute_sequences_energy_sparse(sequences, self.sparse_potts_model, split_couplings_and_fields) + else: + output=frustration.compute_sequences_energy(sequences, self.potts_model, self.mask, split_couplings_and_fields) return output def fields_energy(self, sequence:str = None, ignore_fields_of_gaps:bool = False) -> float: @@ -114,7 +137,7 @@ def fields_energy(self, sequence:str = None, ignore_fields_of_gaps:bool = False) """ if sequence is None: sequence=self.sequence - fields_energy=frustration.compute_fields_energy(sequence, self.potts_model,ignore_fields_of_gaps) + fields_energy=frustration.compute_fields_energy(sequence, self._potts_model,ignore_fields_of_gaps) return fields_energy def couplings_energy(self, sequence:str = None,ignore_couplings_of_gaps:bool = False) -> float: @@ -139,7 +162,10 @@ def couplings_energy(self, sequence:str = None,ignore_couplings_of_gaps:bool = F """ if sequence is None: sequence=self.sequence - couplings_energy=frustration.compute_couplings_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps) + if getattr(self, 'sparse_potts_model', None) is not None: + couplings_energy=frustration.compute_couplings_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps) + else: + couplings_energy=frustration.compute_couplings_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps) return couplings_energy def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask:np.array = None) -> np.array: @@ -202,13 +228,24 @@ def decoy_energy(self, kind:str = 'singleresidue',sequence: str =None) ->np.arra def scores(self): """ - Computes accuracy of DCA predicted contacts by calculating contact scores based on the Frobenius norm + Computes accuracy of DCA predicted contacts by calculating contact scores based on the Frobenius norm. + + Note: In sparse mode, J is reconstructed from contacts only. Non-contact + couplings are zero, so scores at those positions will be zero. For full + DCA contact prediction, construct the model with ``sparse=False``. Returns ------- corr_norm : np.array Contact score matrix (N x N) """ + if getattr(self, 'sparse_potts_model', None) is not None: + logging.warning( + "scores() called on a sparse model: non-contact couplings are " + "zero in sparse mode, so scores may differ from the full model. " + "Use sparse=False for accurate DCA contact prediction scores." + ) + self._ensure_dense_potts_model() return frustration.compute_scores(self.potts_model) def frustration(self, sequence:str = None, kind:str = 'singleresidue', mask:np.array = None, aa_freq:np.array = None, correction:int = 0) -> np.array: diff --git a/frustratometer/frustration/__init__.py b/frustratometer/frustration/__init__.py index a5400d54..8111e944 100644 --- a/frustratometer/frustration/__init__.py +++ b/frustratometer/frustration/__init__.py @@ -24,4 +24,7 @@ 'compute_mask_sparse', 'potts_model_dense_to_sparse', 'potts_model_sparse_to_dense', - 'build_contact_lookup'] + 'build_contact_lookup', + 'compute_native_energy_sparse', + 'compute_couplings_energy_sparse', + 'compute_sequences_energy_sparse'] diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index bc52aec0..af203b18 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -1772,4 +1772,126 @@ def build_contact_lookup(contact_i: np.ndarray, contact_j: np.ndarray, L: int) - lookup_indices[pos] = k current[p] += 1 + return lookup_offsets, lookup_partners, lookup_indices + + +def compute_native_energy_sparse(seq: str, + sparse_potts_model: dict, + ignore_gap_couplings: bool = False, + ignore_gap_fields: bool = False) -> float: + """ + Compute the native energy using a sparse Potts model. + + Equivalent to ``compute_native_energy`` but avoids materializing the full + (L, L) coupling matrix. + + Parameters + ---------- + seq : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model with keys 'h', 'J', 'contact_i', 'contact_j', 'L'. + ignore_gap_couplings : bool + Zero out couplings involving gap positions. Default False. + ignore_gap_fields : bool + Zero out fields at gap positions. Default False. + + Returns + ------- + energy : float + """ + seq_index = np.array([_AA.find(aa) for aa in seq]) + L = len(seq_index) + + h = -sparse_potts_model['h'][np.arange(L), seq_index].copy() + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + J_sparse = sparse_potts_model['J'] + + j_vals = -J_sparse[np.arange(len(contact_i)), seq_index[contact_i], seq_index[contact_j]] + + gap_indices = np.array([i for i, aa in enumerate(seq) if aa == '-']) + + if ignore_gap_fields and len(gap_indices) > 0: + h[gap_indices] = 0.0 + + if ignore_gap_couplings and len(gap_indices) > 0: + gap_set = set(gap_indices) + gap_mask = np.array([contact_i[k] in gap_set or contact_j[k] in gap_set for k in range(len(contact_i))]) + j_vals[gap_mask] = 0.0 + + energy = h.sum() + j_vals.sum() / 2 + return energy + + +def compute_couplings_energy_sparse(seq: str, + sparse_potts_model: dict, + ignore_couplings_of_gaps: bool = False) -> float: + """ + Compute the couplings energy using a sparse Potts model. + + Parameters + ---------- + seq : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model. + ignore_couplings_of_gaps : bool + Zero out couplings involving gap positions. Default False. + + Returns + ------- + couplings_energy : float + """ + seq_index = np.array([_AA.find(aa) for aa in seq]) + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + J_sparse = sparse_potts_model['J'] + + j_vals = -J_sparse[np.arange(len(contact_i)), seq_index[contact_i], seq_index[contact_j]] + + if ignore_couplings_of_gaps: + gap_indices = set(i for i, aa in enumerate(seq) if aa == '-') + if gap_indices: + gap_mask = np.array([contact_i[k] in gap_indices or contact_j[k] in gap_indices for k in range(len(contact_i))]) + j_vals[gap_mask] = 0.0 + + return j_vals.sum() / 2 + + +def compute_sequences_energy_sparse(seqs: list, + sparse_potts_model: dict, + split_couplings_and_fields: bool = False) -> np.ndarray: + """ + Compute energies for multiple sequences using a sparse Potts model. + + Parameters + ---------- + seqs : list of str + Amino acid sequences (all length L). + sparse_potts_model : dict + Sparse Potts model. + split_couplings_and_fields : bool + If True, return (2, N_seqs) array of [fields, couplings]. Default False. + + Returns + ------- + energy : np.ndarray (N_seqs,) or (2, N_seqs) + """ + seq_index = np.array([[_AA.find(aa) for aa in seq] for seq in seqs]) + N_seqs, L = seq_index.shape + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + J_sparse = sparse_potts_model['J'] + + h = -sparse_potts_model['h'][np.arange(L)[np.newaxis, :], seq_index] # (N_seqs, L) + j_vals = -J_sparse[np.arange(len(contact_i)), + seq_index[:, contact_i], + seq_index[:, contact_j]] # (N_seqs, N_contacts) + + if split_couplings_and_fields: + return np.array([h.sum(axis=1), j_vals.sum(axis=1) / 2]) + else: + return h.sum(axis=1) + j_vals.sum(axis=1) / 2 + return lookup_offsets, lookup_partners, lookup_indices \ No newline at end of file diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index 7af4dec9..f0540991 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -419,5 +419,51 @@ def test_expose_indicators(structure, k_electrostatics, min_sequence_separation_ contact_energy_expected = model.couplings_energy() assert np.isclose(contact_energy_predicted,contact_energy_expected), f"Expected energy {contact_energy_expected} but got {contact_energy_predicted}" + +from frustratometer.frustration.frustration import ( + potts_model_dense_to_sparse, + compute_native_energy_sparse, + compute_couplings_energy_sparse, + compute_sequences_energy_sparse, +) + + +@pytest.mark.parametrize("fixture_name", ["awsem_6u5e", "awsem_6u5e_density"]) +def test_sparse_energy_matches_dense(fixture_name, awsem_6u5e, awsem_6u5e_density): + """Sparse native/fields/couplings energy must match dense on real AWSEM models.""" + model = awsem_6u5e if fixture_name == "awsem_6u5e" else awsem_6u5e_density + spm = potts_model_dense_to_sparse(model.potts_model, model.mask) + + dense_native = model.native_energy() + sparse_native = compute_native_energy_sparse(model.sequence, spm) + np.testing.assert_allclose(sparse_native, dense_native, rtol=1e-10) + + dense_couplings = model.couplings_energy() + sparse_couplings = compute_couplings_energy_sparse(model.sequence, spm) + np.testing.assert_allclose(sparse_couplings, dense_couplings, rtol=1e-10) + + # fields + sparse_couplings = sparse_native + np.testing.assert_allclose(model.fields_energy() + sparse_couplings, sparse_native, rtol=1e-10) + + +def test_sparse_sequences_energy_matches_dense(awsem_6u5e): + """Sparse batch energy must match dense for multiple random sequences.""" + model = awsem_6u5e + spm = potts_model_dense_to_sparse(model.potts_model, model.mask) + rng = np.random.default_rng(42) + _AA = '-ACDEFGHIKLMNPQRSTVWY' + seqs = [''.join(rng.choice(list(_AA[1:]), size=len(model.sequence))) for _ in range(5)] + + from frustratometer.frustration.frustration import compute_sequences_energy + dense = compute_sequences_energy(seqs, model.potts_model, model.mask) + sparse = compute_sequences_energy_sparse(seqs, spm) + np.testing.assert_allclose(sparse, dense, rtol=1e-10) + + # Also test split mode + dense_split = compute_sequences_energy(seqs, model.potts_model, model.mask, split_couplings_and_fields=True) + sparse_split = compute_sequences_energy_sparse(seqs, spm, split_couplings_and_fields=True) + np.testing.assert_allclose(sparse_split, dense_split, rtol=1e-10) + + if __name__ == "__main__": pytest.main() From aa33f0314838e89dac81107544c1ed5930b36d39 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 7 Apr 2026 11:52:42 -0500 Subject: [PATCH 08/28] Adds sparse frustration methods --- frustratometer/classes/Frustratometer.py | 46 +++- frustratometer/frustration/__init__.py | 8 +- frustratometer/frustration/frustration.py | 287 ++++++++++++++++++++-- tests/test_awsem_frustratometer.py | 104 ++++++-- 4 files changed, 388 insertions(+), 57 deletions(-) diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index b760f5ec..522497b8 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -192,16 +192,31 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: return self._decoy_fluctuation[kind] if not isinstance(mask, np.ndarray): mask=self.mask - if kind == 'singleresidue': - fluctuation = frustration.compute_singleresidue_decoy_energy_fluctuation(sequence, self.potts_model, mask) - elif kind == 'mutational': - fluctuation = frustration.compute_mutational_decoy_energy_fluctuation(sequence, self.potts_model, mask) - elif kind == 'configurational': - fluctuation = frustration.compute_configurational_decoy_energy_fluctuation(sequence, self.potts_model, mask) - elif kind == 'contact': - fluctuation = frustration.compute_contact_decoy_energy_fluctuation(sequence, self.potts_model, mask) + # Use sparse path when available + _use_sparse = getattr(self, 'sparse_potts_model', None) is not None + if _use_sparse: + if kind == 'singleresidue': + fluctuation = frustration.compute_singleresidue_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) + elif kind == 'mutational': + fluctuation = frustration.compute_mutational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) + elif kind == 'configurational': + mask_mean = self.mask.mean() + fluctuation = frustration.compute_configurational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model, mask_mean) + elif kind == 'contact': + fluctuation = frustration.compute_contact_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) + else: + raise Exception("Wrong kind of decoy generation selected") else: - raise Exception("Wrong kind of decoy generation selected") + if kind == 'singleresidue': + fluctuation = frustration.compute_singleresidue_decoy_energy_fluctuation(sequence, self.potts_model, mask) + elif kind == 'mutational': + fluctuation = frustration.compute_mutational_decoy_energy_fluctuation(sequence, self.potts_model, mask) + elif kind == 'configurational': + fluctuation = frustration.compute_configurational_decoy_energy_fluctuation(sequence, self.potts_model, mask) + elif kind == 'contact': + fluctuation = frustration.compute_contact_decoy_energy_fluctuation(sequence, self.potts_model, mask) + else: + raise Exception("Wrong kind of decoy generation selected") self._decoy_fluctuation[kind] = fluctuation return fluctuation @@ -284,7 +299,18 @@ def frustration(self, sequence:str = None, kind:str = 'singleresidue', mask:np.a return self.configurational_frustration(None, correction) if aa_freq is None: aa_freq = self.contact_freq - frustration_values=frustration.compute_pair_frustration(decoy_fluctuation, aa_freq, correction) + # Sparse decoy fluctuation has shape (N_contacts, 21, 21) — use sparse pair frustration, then densify + _use_sparse = getattr(self, 'sparse_potts_model', None) is not None + if _use_sparse and decoy_fluctuation.ndim == 3: + sparse_frust = frustration.compute_pair_frustration_sparse(decoy_fluctuation, aa_freq, correction) + frustration_values = frustration.sparse_frustration_to_dense( + sparse_frust, + self.sparse_potts_model['contact_i'], + self.sparse_potts_model['contact_j'], + self.sparse_potts_model['L'], + ) + else: + frustration_values=frustration.compute_pair_frustration(decoy_fluctuation, aa_freq, correction) return frustration_values def plot_decoy_energy(self, sequence:str = None, kind:str = 'singleresidue', method:str = 'clustermap'): diff --git a/frustratometer/frustration/__init__.py b/frustratometer/frustration/__init__.py index 8111e944..6e85b95e 100644 --- a/frustratometer/frustration/__init__.py +++ b/frustratometer/frustration/__init__.py @@ -27,4 +27,10 @@ 'build_contact_lookup', 'compute_native_energy_sparse', 'compute_couplings_energy_sparse', - 'compute_sequences_energy_sparse'] + 'compute_sequences_energy_sparse', + 'compute_singleresidue_decoy_energy_fluctuation_sparse', + 'compute_mutational_decoy_energy_fluctuation_sparse', + 'compute_configurational_decoy_energy_fluctuation_sparse', + 'compute_contact_decoy_energy_fluctuation_sparse', + 'compute_pair_frustration_sparse', + 'sparse_frustration_to_dense'] diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index af203b18..25ba72e8 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -1754,23 +1754,15 @@ def build_contact_lookup(contact_i: np.ndarray, contact_j: np.ndarray, L: int) - """ N = len(contact_i) # Count contacts per position (using contact_i as the "row") - counts = np.zeros(L, dtype=np.intp) - for k in range(N): - counts[contact_i[k]] += 1 + counts = np.bincount(contact_i, minlength=L).astype(np.intp) lookup_offsets = np.zeros(L + 1, dtype=np.intp) np.cumsum(counts, out=lookup_offsets[1:]) - # Fill partner and index arrays - lookup_partners = np.empty(N, dtype=np.intp) - lookup_indices = np.empty(N, dtype=np.intp) - current = lookup_offsets[:-1].copy() - for k in range(N): - p = contact_i[k] - pos = current[p] - lookup_partners[pos] = contact_j[k] - lookup_indices[pos] = k - current[p] += 1 + # Sort by contact_i to group contacts by position, then fill partner/index arrays + order = np.argsort(contact_i, kind='stable') + lookup_partners = contact_j[order].astype(np.intp) + lookup_indices = order.astype(np.intp) return lookup_offsets, lookup_partners, lookup_indices @@ -1816,8 +1808,7 @@ def compute_native_energy_sparse(seq: str, h[gap_indices] = 0.0 if ignore_gap_couplings and len(gap_indices) > 0: - gap_set = set(gap_indices) - gap_mask = np.array([contact_i[k] in gap_set or contact_j[k] in gap_set for k in range(len(contact_i))]) + gap_mask = np.isin(contact_i, gap_indices) | np.isin(contact_j, gap_indices) j_vals[gap_mask] = 0.0 energy = h.sum() + j_vals.sum() / 2 @@ -1851,9 +1842,9 @@ def compute_couplings_energy_sparse(seq: str, j_vals = -J_sparse[np.arange(len(contact_i)), seq_index[contact_i], seq_index[contact_j]] if ignore_couplings_of_gaps: - gap_indices = set(i for i, aa in enumerate(seq) if aa == '-') - if gap_indices: - gap_mask = np.array([contact_i[k] in gap_indices or contact_j[k] in gap_indices for k in range(len(contact_i))]) + gap_indices = np.array([i for i, aa in enumerate(seq) if aa == '-']) + if len(gap_indices) > 0: + gap_mask = np.isin(contact_i, gap_indices) | np.isin(contact_j, gap_indices) j_vals[gap_mask] = 0.0 return j_vals.sum() / 2 @@ -1893,5 +1884,263 @@ def compute_sequences_energy_sparse(seqs: list, return np.array([h.sum(axis=1), j_vals.sum(axis=1) / 2]) else: return h.sum(axis=1) + j_vals.sum(axis=1) / 2 + + return lookup_offsets, lookup_partners, lookup_indices + + +def compute_singleresidue_decoy_energy_fluctuation_sparse(seq: str, + sparse_potts_model: dict) -> np.ndarray: + """ + Compute single-residue decoy energy fluctuation using a sparse Potts model. + + Returns the same (L, 21) shape as the dense version. + + Parameters + ---------- + seq : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model. + + Returns + ------- + decoy_energy : np.ndarray (L, 21) + """ + seq_index = np.array([_AA.find(aa) for aa in seq]) + L = len(seq_index) + h = sparse_potts_model['h'] + J_sparse = sparse_potts_model['J'] + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + N_contacts = len(contact_i) + + # Fields correction: -(h[i, aa_new] - h[i, aa_native]) + decoy_energy = np.zeros((L, 21)) + decoy_energy -= (h - h[np.arange(L), seq_index][:, np.newaxis]) + + # Couplings correction via V + # V[j, a] = sum_i J[i, j, seq[i], a] * mask[i, j] + # Dense formula: correction_i(a) = V[i, seq[i]] - V[i, a] + V = np.zeros((L, 21)) + values = J_sparse[np.arange(N_contacts), seq_index[contact_i], :] # (N_contacts, 21) + np.add.at(V, contact_j, values) + + decoy_energy += V[np.arange(L), seq_index][:, np.newaxis] - V + + return decoy_energy + + +def compute_mutational_decoy_energy_fluctuation_sparse(seq: str, + sparse_potts_model: dict) -> np.ndarray: + """ + Compute mutational decoy energy fluctuation using a sparse Potts model. + + Returns (N_contacts, 21, 21) instead of (L, L, 21, 21). + + Parameters + ---------- + seq : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model. + + Returns + ------- + decoy_energy : np.ndarray (N_contacts, 21, 21) + Energy changes for each contact upon mutating both residues. + """ + seq_index = np.array([_AA.find(aa) for aa in seq]) + L = len(seq_index) + h = sparse_potts_model['h'] + J_sparse = sparse_potts_model['J'] + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + N_contacts = len(contact_i) + + aa_range = np.arange(21) + idx = np.arange(N_contacts) + pos1 = contact_i + pos2 = contact_j + + # Fields correction + decoy_energy = np.zeros((N_contacts, 21, 21)) + dh1 = h[pos1[:, np.newaxis], aa_range[np.newaxis, :]] - h[pos1, seq_index[pos1]][:, np.newaxis] # (N, 21) + dh2 = h[pos2[:, np.newaxis], aa_range[np.newaxis, :]] - h[pos2, seq_index[pos2]][:, np.newaxis] # (N, 21) + decoy_energy -= dh1[:, :, np.newaxis] + decoy_energy -= dh2[:, np.newaxis, :] + + # Environment coupling correction via V + V = np.zeros((L, 21)) + values = J_sparse[np.arange(N_contacts), seq_index[contact_i], :] # (N_contacts, 21) + np.add.at(V, contact_j, values) + + decoy_energy += (V[pos1, seq_index[pos1]][:, np.newaxis, np.newaxis] + - V[pos1][:, :, np.newaxis] + + V[pos2, seq_index[pos2]][:, np.newaxis, np.newaxis] + - V[pos2][:, np.newaxis, :]) + + # Self-interaction corrections (pair i,j was counted in V for both pos1 and pos2) + decoy_energy -= J_sparse[idx, seq_index[pos1], seq_index[pos2]][:, np.newaxis, np.newaxis] + term2 = J_sparse[idx[:, np.newaxis], aa_range[np.newaxis, :], seq_index[pos2][:, np.newaxis]] # (N, 21) + decoy_energy += term2[:, :, np.newaxis] + term3 = J_sparse[idx[:, np.newaxis], seq_index[pos1][:, np.newaxis], aa_range[np.newaxis, :]] # (N, 21) + decoy_energy += term3[:, np.newaxis, :] + decoy_energy -= J_sparse + + return decoy_energy + + +def compute_configurational_decoy_energy_fluctuation_sparse(seq: str, + sparse_potts_model: dict, + mask_mean: float) -> np.ndarray: + """ + Compute pseudo-configurational decoy energy fluctuation using a sparse Potts model. + + Uses ``mask_mean`` as a scalar weight for decoy interactions (shuffled densities). + + Parameters + ---------- + seq : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model. + mask_mean : float + Mean of the original dense mask, used as weight for configurational decoys. + + Returns + ------- + decoy_energy : np.ndarray (N_contacts, 21, 21) + """ + seq_index = np.array([_AA.find(aa) for aa in seq]) + L = len(seq_index) + h = sparse_potts_model['h'] + J_sparse = sparse_potts_model['J'] + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + N_contacts = len(contact_i) + + aa_range = np.arange(21) + idx = np.arange(N_contacts) + pos1 = contact_i + pos2 = contact_j + + # Fields correction + decoy_energy = np.zeros((N_contacts, 21, 21)) + dh1 = h[pos1[:, np.newaxis], aa_range[np.newaxis, :]] - h[pos1, seq_index[pos1]][:, np.newaxis] + dh2 = h[pos2[:, np.newaxis], aa_range[np.newaxis, :]] - h[pos2, seq_index[pos2]][:, np.newaxis] + decoy_energy -= dh1[:, :, np.newaxis] + decoy_energy -= dh2[:, np.newaxis, :] + + # Environment coupling correction + V = np.zeros((L, 21)) + values = J_sparse[np.arange(N_contacts), seq_index[contact_i], :] # (N_contacts, 21) + np.add.at(V, contact_j, values) + + # Native environment uses actual mask (contacts), decoy uses mask_mean + decoy_energy += (V[pos1, seq_index[pos1]][:, np.newaxis, np.newaxis] + - V[pos1][:, :, np.newaxis] * mask_mean + + V[pos2, seq_index[pos2]][:, np.newaxis, np.newaxis] + - V[pos2][:, np.newaxis, :] * mask_mean) + + # Self-interaction corrections + decoy_energy -= J_sparse[idx, seq_index[pos1], seq_index[pos2]][:, np.newaxis, np.newaxis] + term2 = J_sparse[idx[:, np.newaxis], aa_range[np.newaxis, :], seq_index[pos2][:, np.newaxis]] * mask_mean + decoy_energy += term2[:, :, np.newaxis] + term3 = J_sparse[idx[:, np.newaxis], seq_index[pos1][:, np.newaxis], aa_range[np.newaxis, :]] * mask_mean + decoy_energy += term3[:, np.newaxis, :] + decoy_energy -= J_sparse * mask_mean + + return decoy_energy + + +def compute_contact_decoy_energy_fluctuation_sparse(seq: str, + sparse_potts_model: dict) -> np.ndarray: + """ + Compute contact decoy energy fluctuation using a sparse Potts model. + + Only the coupling at the contact itself changes. + + Parameters + ---------- + seq : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model. + + Returns + ------- + decoy_energy : np.ndarray (N_contacts, 21, 21) + """ + seq_index = np.array([_AA.find(aa) for aa in seq]) + J_sparse = sparse_potts_model['J'] + contact_i = sparse_potts_model['contact_i'] + contact_j = sparse_potts_model['contact_j'] + N_contacts = len(contact_i) + idx = np.arange(N_contacts) + + # Old coupling - new coupling (mask is implicit = 1 for all stored contacts) + decoy_energy = (J_sparse[idx, seq_index[contact_i], seq_index[contact_j]][:, np.newaxis, np.newaxis] + - J_sparse) + return decoy_energy + + +def compute_pair_frustration_sparse(decoy_fluctuation: np.ndarray, + contact_freq: Union[None, np.ndarray] = None, + correction: float = 0) -> np.ndarray: + """ + Compute pair frustration indices from sparse decoy fluctuation. + + Parameters + ---------- + decoy_fluctuation : np.ndarray (N_contacts, 21, 21) + Decoy energy fluctuation at each contact. + contact_freq : np.ndarray (21, 21) or None + Amino acid pair frequencies as weights. If None, uniform. + correction : float + Added to denominator to avoid division by zero. Default 0. + + Returns + ------- + frustration : np.ndarray (N_contacts,) + Frustration index for each contact. + """ + if contact_freq is None: + contact_freq = np.ones((21, 21)) + N_contacts = decoy_fluctuation.shape[0] + flat_fluct = decoy_fluctuation.reshape(N_contacts, 21 * 21) + flat_freq = contact_freq.flatten() + average = np.average(flat_fluct, weights=flat_freq, axis=1) + variance = np.average((flat_fluct - average[:, np.newaxis]) ** 2, weights=flat_freq, axis=1) + std_energy = np.sqrt(variance) + frustration = -(-average / (std_energy + correction)) + return frustration + + +def sparse_frustration_to_dense(frustration_values: np.ndarray, + contact_i: np.ndarray, + contact_j: np.ndarray, + L: int) -> np.ndarray: + """ + Convert sparse frustration values to a dense (L, L) matrix. + + Parameters + ---------- + frustration_values : np.ndarray (N_contacts,) + Frustration index for each contact. + contact_i : np.ndarray (N_contacts,) + Row indices. + contact_j : np.ndarray (N_contacts,) + Column indices. + L : int + Sequence length. + + Returns + ------- + dense : np.ndarray (L, L) + Dense frustration matrix (zero at non-contact positions). + """ + dense = np.zeros((L, L)) + dense[contact_i, contact_j] = frustration_values + return dense - return lookup_offsets, lookup_partners, lookup_indices \ No newline at end of file + \ No newline at end of file diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index f0540991..a417c452 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -424,45 +424,95 @@ def test_expose_indicators(structure, k_electrostatics, min_sequence_separation_ potts_model_dense_to_sparse, compute_native_energy_sparse, compute_couplings_energy_sparse, - compute_sequences_energy_sparse, + compute_singleresidue_decoy_energy_fluctuation_sparse, + compute_mutational_decoy_energy_fluctuation_sparse, + compute_configurational_decoy_energy_fluctuation_sparse, + compute_contact_decoy_energy_fluctuation_sparse, + compute_pair_frustration, + compute_pair_frustration_sparse, + sparse_frustration_to_dense, ) +# --- Sparse cross-validation fixtures (module-scoped, computed once) --- + +@pytest.fixture(scope="module") +def sparse_6u5e(awsem_6u5e): + return potts_model_dense_to_sparse(awsem_6u5e.potts_model, awsem_6u5e.mask) + +@pytest.fixture(scope="module") +def sparse_6u5e_density(awsem_6u5e_density): + return potts_model_dense_to_sparse(awsem_6u5e_density.potts_model, awsem_6u5e_density.mask) + +@pytest.fixture(scope="module") +def dense_decoys_6u5e_density(awsem_6u5e_density): + """Compute dense decoy fluctuations once — shared by decoy and frustration tests.""" + m = awsem_6u5e_density + return { + 'singleresidue': m.decoy_fluctuation(kind='singleresidue'), + 'mutational': m.decoy_fluctuation(kind='mutational'), + 'contact': m.decoy_fluctuation(kind='contact'), + 'configurational': m.decoy_fluctuation(kind='configurational'), + } + +# --- Sparse cross-validation tests --- @pytest.mark.parametrize("fixture_name", ["awsem_6u5e", "awsem_6u5e_density"]) -def test_sparse_energy_matches_dense(fixture_name, awsem_6u5e, awsem_6u5e_density): - """Sparse native/fields/couplings energy must match dense on real AWSEM models.""" - model = awsem_6u5e if fixture_name == "awsem_6u5e" else awsem_6u5e_density - spm = potts_model_dense_to_sparse(model.potts_model, model.mask) +def test_sparse_energy_matches_dense(fixture_name, awsem_6u5e, awsem_6u5e_density, sparse_6u5e, sparse_6u5e_density): + """Sparse native/couplings energy must reproduce dense on real AWSEM models.""" + if fixture_name == "awsem_6u5e": + model, spm = awsem_6u5e, sparse_6u5e + else: + model, spm = awsem_6u5e_density, sparse_6u5e_density dense_native = model.native_energy() - sparse_native = compute_native_energy_sparse(model.sequence, spm) - np.testing.assert_allclose(sparse_native, dense_native, rtol=1e-10) - dense_couplings = model.couplings_energy() - sparse_couplings = compute_couplings_energy_sparse(model.sequence, spm) - np.testing.assert_allclose(sparse_couplings, dense_couplings, rtol=1e-10) + dense_fields = model.fields_energy() - # fields + sparse_couplings = sparse_native - np.testing.assert_allclose(model.fields_energy() + sparse_couplings, sparse_native, rtol=1e-10) + np.testing.assert_allclose(compute_native_energy_sparse(model.sequence, spm), dense_native, rtol=1e-10) + np.testing.assert_allclose(compute_couplings_energy_sparse(model.sequence, spm), dense_couplings, rtol=1e-10) + np.testing.assert_allclose(dense_fields + compute_couplings_energy_sparse(model.sequence, spm), dense_native, rtol=1e-10) -def test_sparse_sequences_energy_matches_dense(awsem_6u5e): - """Sparse batch energy must match dense for multiple random sequences.""" - model = awsem_6u5e - spm = potts_model_dense_to_sparse(model.potts_model, model.mask) - rng = np.random.default_rng(42) - _AA = '-ACDEFGHIKLMNPQRSTVWY' - seqs = [''.join(rng.choice(list(_AA[1:]), size=len(model.sequence))) for _ in range(5)] +@pytest.mark.parametrize("kind", ["singleresidue", "mutational", "contact", "configurational"]) +def test_sparse_decoy_matches_dense(kind, awsem_6u5e_density, sparse_6u5e_density, dense_decoys_6u5e_density): + """Sparse decoy fluctuation must match dense for all four kinds.""" + model = awsem_6u5e_density + spm = sparse_6u5e_density + dense = dense_decoys_6u5e_density[kind] + + if kind == 'singleresidue': + sparse = compute_singleresidue_decoy_energy_fluctuation_sparse(model.sequence, spm) + np.testing.assert_allclose(sparse, dense, atol=1e-4) + elif kind == 'configurational': + sparse = compute_configurational_decoy_energy_fluctuation_sparse(model.sequence, spm, model.mask.mean()) + ci, cj = spm['contact_i'], spm['contact_j'] + np.testing.assert_allclose(sparse, dense[ci, cj], atol=1e-4) + else: + sparse_func = (compute_mutational_decoy_energy_fluctuation_sparse if kind == 'mutational' + else compute_contact_decoy_energy_fluctuation_sparse) + sparse = sparse_func(model.sequence, spm) + ci, cj = spm['contact_i'], spm['contact_j'] + np.testing.assert_allclose(sparse, dense[ci, cj], atol=1e-4) + + +@pytest.mark.parametrize("kind", ["mutational", "contact"]) +def test_sparse_frustration_matches_dense(kind, awsem_6u5e_density, sparse_6u5e_density, dense_decoys_6u5e_density): + """Sparse frustration pipeline must match dense (reuses cached dense decoys).""" + model = awsem_6u5e_density + spm = sparse_6u5e_density + + # Dense frustration from cached decoys (no recomputation) + dense_frust = compute_pair_frustration(dense_decoys_6u5e_density[kind], model.contact_freq) - from frustratometer.frustration.frustration import compute_sequences_energy - dense = compute_sequences_energy(seqs, model.potts_model, model.mask) - sparse = compute_sequences_energy_sparse(seqs, spm) - np.testing.assert_allclose(sparse, dense, rtol=1e-10) + # Sparse pipeline: decoy → frustration → densify + sparse_func = (compute_mutational_decoy_energy_fluctuation_sparse if kind == 'mutational' + else compute_contact_decoy_energy_fluctuation_sparse) + sparse_decoy = sparse_func(model.sequence, spm) + sparse_frust = compute_pair_frustration_sparse(sparse_decoy, model.contact_freq) + dense_from_sparse = sparse_frustration_to_dense(sparse_frust, spm['contact_i'], spm['contact_j'], spm['L']) - # Also test split mode - dense_split = compute_sequences_energy(seqs, model.potts_model, model.mask, split_couplings_and_fields=True) - sparse_split = compute_sequences_energy_sparse(seqs, spm, split_couplings_and_fields=True) - np.testing.assert_allclose(sparse_split, dense_split, rtol=1e-10) + ci, cj = spm['contact_i'], spm['contact_j'] + np.testing.assert_allclose(dense_from_sparse[ci, cj], dense_frust[ci, cj], atol=1e-4) if __name__ == "__main__": From efcb2c6783460d12060d69343d817fec7e21c9c0 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 7 Apr 2026 16:01:44 -0500 Subject: [PATCH 09/28] Adds electrostatics corrections --- docs/index.rst | 1 + docs/sparse.rst | 581 ++++++++++++++++++++++ frustratometer/classes/Frustratometer.py | 54 +- frustratometer/frustration/__init__.py | 14 +- frustratometer/frustration/frustration.py | 331 +++++++++++- tests/test_awsem_frustratometer.py | 118 ++++- 6 files changed, 1057 insertions(+), 42 deletions(-) create mode 100644 docs/sparse.rst diff --git a/docs/index.rst b/docs/index.rst index f2cccfcf..324054a5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,6 +14,7 @@ Welcome to Frustratometer's documentation! installation examples_awsem examples_dca + sparse api_classes api_modules diff --git a/docs/sparse.rst b/docs/sparse.rst new file mode 100644 index 00000000..f4cd0dee --- /dev/null +++ b/docs/sparse.rst @@ -0,0 +1,581 @@ +Sparse Calculations +=================== + +For large proteins, the standard dense Potts model representation stores +a coupling tensor :math:`J` of shape :math:`(L, L, 21, 21)`, which grows +as :math:`O(L^2)` and can require gigabytes of memory. The dense representation +can provide a more straight-forward view of the interactions, but it is computationally expensive. +The sparse framework avoids this by storing only the couplings at positions where the contact mask +is nonzero — typically a small fraction of all pairs. + +Sparse Potts Model +------------------ + +The sparse Potts model is a dictionary with the following keys: + +- ``h`` — shape :math:`(L, 21)`: fields (identical to dense) +- ``J`` — shape :math:`(N_\text{contacts}, 21, 21)`: couplings only at contact positions +- ``contact_i``, ``contact_j`` — shape :math:`(N_\text{contacts},)`: row and column indices of each contact +- ``L`` — sequence length + +For a protein of length :math:`L = 163` with :math:`N_\text{contacts} \approx 2{,}200`, +the dense :math:`J` tensor uses :math:`163^2 \times 21^2 \approx 12\text{M}` floats +(:math:`\sim 94\text{ MB}`), while the sparse representation uses only +:math:`2{,}200 \times 441 \approx 970\text{K}` floats (:math:`\sim 7.6\text{ MB}`). + +Conversion +^^^^^^^^^^ + +.. autofunction:: frustratometer.frustration.frustration.potts_model_dense_to_sparse +.. autofunction:: frustratometer.frustration.frustration.potts_model_sparse_to_dense + +Contact Lookup +^^^^^^^^^^^^^^ + +To efficiently compute per-residue sums over contacts (e.g. for single-residue +decoy fluctuations), a CSR-like lookup structure groups contacts by position: + +.. autofunction:: frustratometer.frustration.frustration.build_contact_lookup + +Sparse Mask +^^^^^^^^^^^ + +Computes the mask without materializing a full :math:`(L, L)` matrix: + +.. autofunction:: frustratometer.frustration.frustration.compute_mask_sparse + + +Sparse Energy Functions +----------------------- + +These functions compute the same energies as their dense counterparts but +operate directly on the sparse Potts model, avoiding any :math:`(L, L)` or +:math:`(L, L, 21, 21)` intermediate arrays. + +.. autofunction:: frustratometer.frustration.frustration.compute_native_energy_sparse +.. autofunction:: frustratometer.frustration.frustration.compute_couplings_energy_sparse +.. autofunction:: frustratometer.frustration.frustration.compute_sequences_energy_sparse + + +Sparse Decoy Fluctuations +-------------------------- + +Decoy fluctuations measure how the energy changes under hypothetical mutations. +The dense versions produce tensors of shape :math:`(L, 21)` (single-residue) or +:math:`(L, L, 21, 21)` (pair). The sparse versions produce :math:`(L, 21)` for +single-residue and :math:`(N_\text{contacts}, 21, 21)` for pair kinds — only +storing values at contact positions. + +.. autofunction:: frustratometer.frustration.frustration.compute_singleresidue_decoy_energy_fluctuation_sparse +.. autofunction:: frustratometer.frustration.frustration.compute_mutational_decoy_energy_fluctuation_sparse +.. autofunction:: frustratometer.frustration.frustration.compute_pseudoconfigurational_decoy_energy_fluctuation_sparse +.. autofunction:: frustratometer.frustration.frustration.compute_contact_decoy_energy_fluctuation_sparse + + +Sparse Frustration +------------------ + +.. autofunction:: frustratometer.frustration.frustration.compute_pair_frustration_sparse +.. autofunction:: frustratometer.frustration.frustration.sparse_frustration_to_dense + + +Electrostatic Corrections +-------------------------- + +The sparse Potts model stores couplings only at contact positions, +:math:`(N_\text{contacts}, Q, Q)` instead of :math:`(L, L, Q, Q)`, which saves +memory when :math:`N_\text{contacts} \ll L^2`. Electrostatics, however, is a +long-ranged interaction. Distant residues interact through the screened Coulomb +potential. In the dense AWSEM formulation, the electrostatic contribution is +folded directly into the coupling tensor as + +.. math:: + + V_{ij}^{\mathrm{elec}}(a,b) + = + \Gamma^{\mathrm{elec}}_{ij}\, q(a)\, q(b), + +where :math:`Q = 21` is the number of amino-acid types (including the gap +state). If we tried to include electrostatics in the sparse couplings, the +number of nonzero contacts would grow to :math:`N_\text{contacts} \sim L^2` +(every pair interacts), defeating the purpose of a sparse representation. + +However the amino-acid dependence enters only through the charge :math:`q(a)`, +a single number per amino acid, and the geometric dependence enters only through +:math:`\Gamma^{\mathrm{elec}}_{ij}`, a single number per residue pair. So the +full electrostatic coupling is determined by an :math:`(L, L)` matrix of +geometric factors and a :math:`(Q,)` vector of charges instead of a +four-dimensional tensor. This reduces the storage from :math:`L^2 Q^2` to +:math:`L^2 + Q`: the :math:`(L, L)` indicator matrix is still needed +(electrostatics is long-ranged and position-dependent, so it cannot be +compressed further without the coordinates), but it is :math:`Q^2 = 441` times +smaller than the dense coupling tensor. + +For the current electrostatic model each amino-acid type :math:`a` is assigned a +charge :math:`q(a)`, where D and E (aspartate, glutamate) have a charge of +:math:`-1` and K and R have a charge of :math:`+1` with all others having 0 +charge. + +The strength of the electrostatic interaction between residues :math:`i` and +:math:`j` is described by the screened Coulomb (Debye--Hückel) kernel: + +.. math:: + + \Gamma^{\mathrm{elec}}_{ij} + = + -k_{\mathrm{elec}} + \frac{\exp(-r_{ij}/l_D)}{r_{ij}}, + +where :math:`r_{ij}` is the inter-residue distance, +:math:`k_{\mathrm{elec}}` is the electrostatic coupling constant, and +:math:`l_D` is the Debye screening length. Each value is always negative +(attractive for opposite charges). Pairs with sequence separation below a +minimum threshold are usually excluded from this interaction. + +.. autofunction:: frustratometer.frustration.frustration.compute_elec_indicator + + +Definitions +^^^^^^^^^^^ + +Before computing the sparse electrostatics, we precompute a small set of summary +quantities from the native structure. These are stored in a dictionary and reused +by all correction functions. + +- :math:`\mathcal{M}_{ij}`: the frustration contact mask. When electrostatics is + enabled, this mask enforces only a minimum sequence separation (no distance + cutoff), so the sums below include all long-range electrostatic interactions. +- :math:`q_i^N`: the charge of the native amino acid at position :math:`i`. +- :math:`\Gamma^{\mathrm{elec}}_{ij}`: the full :math:`(L \times L)` pairwise + electrostatic indicator matrix. This matrix must be computed at all residue + pairs because the potentials :math:`\phi_i` and :math:`\phi_i^{\mathrm{raw}}` + require summing over distant residues. +- :math:`\phi_i^{\mathrm{raw}} = \sum_j \Gamma^{\mathrm{elec}}_{ij}\,q_j^N`: + the electrostatic potential at position :math:`i` without the contact mask + (only needed for pseudo-configurational decoys, which average over masked + configurations). +- :math:`\phi_i = \sum_j \Gamma^{\mathrm{elec}}_{ij}\,\mathcal{M}_{ij}\,q_j^N`: + the electrostatic potential felt by residue :math:`i` from its native + environment. +- :math:`\bar{m}`: the mean value of :math:`\mathcal{M}_{ij}`, representing the + average contact density. + +.. autofunction:: frustratometer.frustration.frustration.build_elec_data + + +Native energy correction +^^^^^^^^^^^^^^^^^^^^^^^^ + +The electrostatic contribution to the native energy is + +.. math:: + + V^{\mathrm{elec},N} + = + -\frac{1}{2}\sum_{i,j} + \Gamma^{\mathrm{elec}}_{ij}\,\mathcal{M}_{ij}\,q_i^N\,q_j^N. + +This is added to the base native energy :math:`V^{(0),N}` from the other terms. +The factor of :math:`\tfrac{1}{2}` avoids double-counting the symmetric +:math:`(i,j)` and :math:`(j,i)` contributions. + +.. autofunction:: frustratometer.frustration.frustration.compute_native_energy_elec + + +Decoy corrections +^^^^^^^^^^^^^^^^^ + +Each decoy type requires a different correction formula, because each type +varies different degrees of freedom. + +**Single-residue decoys.** +In single-residue decoys, we compute the change in energy if we mutate position +:math:`i` from its native amino acid (charge :math:`q_i^N`) to type :math:`a` +(charge :math:`q(a)`), while every other position keeps its native identity. +The change in electrostatic energy is the charge difference times the +electrostatic potential at that position: + +.. math:: + + \delta V_i^{\mathrm{elec}}(a) + = + -(q(a) - q_i^N)\,\phi_i. + +.. autofunction:: frustratometer.frustration.frustration.apply_elec_correction_singleresidue + +**Mutational decoys.** +Both positions :math:`i` and :math:`j` are mutated simultaneously to types +:math:`a` and :math:`b`, while the rest of the protein stays native. This is +more complex because mutating :math:`i` and :math:`j` changes not only their +direct interaction, but also each residue's interaction with the entire native +electrostatic environment. + +We define the charge shifts :math:`\delta q_i(a) = q(a) - q_i^N` and +:math:`\delta q_j(b) = q(b) - q_j^N`. The correction has three terms: + +.. math:: + + \delta V_{ij}^{\mathrm{elec,mut}}(a,b) + = + -\delta q_i(a)\,\phi_i + -\,\delta q_j(b)\,\phi_j + -\,\Gamma^{\mathrm{elec}}_{ij}\,\delta q_i(a)\,\delta q_j(b) + +The three terms are: + +1. **Environment of** :math:`i`: Changing :math:`i`'s charge by + :math:`\delta q_i(a)` in the electrostatic field :math:`\phi_i`. +2. **Environment of** :math:`j`: Changing :math:`j`'s charge by + :math:`\delta q_j(b)` in the electrostatic field :math:`\phi_j`. +3. **Direct interaction**: The potential :math:`\phi_i` already included the + contribution from :math:`j` (with its native charge) and vice versa. This + term corrects for the missing new :math:`i`--:math:`j` interaction and + removes the double-counted one. + +The result has shape :math:`(N_\text{contacts}, Q, Q)`. + +.. autofunction:: frustratometer.frustration.frustration.apply_elec_correction_mutational + +**Contact decoys.** +The amino-acid pair :math:`(a,b)` at contact :math:`(i,j)` is drawn randomly, +but the rest of the protein stays native. Only the direct electrostatic +interaction between positions :math:`i` and :math:`j` changes; the interactions +of :math:`i` and :math:`j` with the rest of the chain are unaffected. The +correction is simply the difference between the native and decoy direct +interactions: + +.. math:: + + \delta V_{ij}^{\mathrm{elec,ct}}(a,b) + = + \Gamma^{\mathrm{elec}}_{ij}\,(q_i^N q_j^N - q(a)\, q(b)). + +When the native pair is uncharged (:math:`q_i^N q_j^N = 0`), the correction +reduces to :math:`-\Gamma^{\mathrm{elec}}_{ij}\,q(a)\,q(b)`. The result has +shape :math:`(N_\text{contacts}, Q, Q)`. + +.. autofunction:: frustratometer.frustration.frustration.apply_elec_correction_contact + +**Pseudo-configurational decoys.** +Both the amino-acid pair and the contact geometry change: the native contact mask +:math:`\mathcal{M}_{ij}` is replaced by its average value :math:`\bar{m}`, +simulating a random contact geometry at each position. (This is an analytical +approximation; the real configurational frustration in AWSEM uses explicit Monte +Carlo decoys.) Under the decoy mask, the relevant potential becomes +:math:`\bar{m}\,\phi_i^{\mathrm{raw}}` — the unmasked potential scaled by the +average contact density. + +The correction decomposes into four coefficients in the basis +:math:`\{1, q(a), q(b), q(a)\,q(b)\}`: + +.. math:: + + \delta V_{ij}^{\mathrm{elec,cfg}}(a,b) + = + c_{00} + c_{10}\,q(a) + c_{01}\,q(b) + c_{11}\,q(a)\,q(b), + +where: + +.. math:: + + c_{00} &= q_i^N \phi_i + q_j^N \phi_j + - \Gamma^{\mathrm{elec}}_{ij}\, q_i^N q_j^N\, \mathcal{M}_{ij}, \\ + c_{10} &= \bar{m} \left(\Gamma^{\mathrm{elec}}_{ij}\, q_j^N - \phi_i^{\mathrm{raw}}\right), \\ + c_{01} &= \bar{m} \left(\Gamma^{\mathrm{elec}}_{ij}\, q_i^N - \phi_j^{\mathrm{raw}}\right), \\ + c_{11} &= -\bar{m}\, \Gamma^{\mathrm{elec}}_{ij}. + +- :math:`c_{00}` is a constant offset: the electrostatic energy of the native + charges evaluated under the native mask. +- :math:`c_{10}` multiplies :math:`q(a)` and captures how the decoy charge at + position :math:`i` interacts with the averaged environment. +- :math:`c_{01}` is the symmetric counterpart for position :math:`j`. +- :math:`c_{11}` multiplies :math:`q(a)\,q(b)` and represents the direct + :math:`i`--:math:`j` electrostatic interaction under the averaged mask. + +The result has shape :math:`(N_\text{contacts}, Q, Q)`. + +.. autofunction:: frustratometer.frustration.frustration.apply_elec_correction_pseudoconfigurational + + +Corrected frustration statistics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The frustration index at contact :math:`(i,j)` is + +.. math:: + + F_{ij} = -\frac{V_{ij}^N - \langle V_{ij}^U \rangle}{\sigma_{ij}^U}, + +where :math:`V_{ij}^N` is the native energy at the contact, +:math:`\langle V_{ij}^U \rangle` is the mean over the decoy (unfolded) ensemble, +and :math:`\sigma_{ij}^U` is the corresponding standard deviation. Adding +electrostatic corrections means the total decoy energy is +:math:`V_{ij}^{\mathrm{tot}}(a,b) = V_{ij}^{(0)}(a,b) + \delta V_{ij}^{\mathrm{elec}}(a,b)`, +where :math:`V_{ij}^{(0)}` comes from the base Potts model. The goal is to +compute the mean and variance of this sum exactly, without creating +:math:`(Q \times Q)` correction arrays. + +**Bilinear structure.** +All four corrections depend on amino-acid identity only through the charge +:math:`q(a)`. Their statistics can be computed exactly from a few scalar or +:math:`(2 \times 2)` operations, without enumerating all :math:`Q` (or +:math:`Q^2`) decoy types. + +*Single-residue* is the simplest case. The correction +:math:`\delta V_i^{\mathrm{elec}}(a) = -(q(a) - q_i^N)\,\phi_i` depends on +only one amino-acid index, so it is linear rather than bilinear. Its mean and +variance over the decoy ensemble are: + +.. math:: + + \mu_i^{\mathrm{elec}} = -(\bar{q} - q_i^N)\,\phi_i, + \qquad + \sigma_i^{2,\mathrm{elec}} = \sigma_q^2\,\phi_i^2, + +where :math:`\bar{q} = \sum_a p(a)\,q(a)` and +:math:`\sigma_q^2 = \sum_a p(a)\,q(a)^2 - \bar{q}^2` are the mean and variance +of the charge under the amino-acid frequency distribution :math:`p(a)`. The +covariance with the base single-residue energy :math:`V_i^{(0)}(a)` is +:math:`\mathrm{Cov}_i^{(0,\mathrm{elec})} = -\phi_i \, \mathrm{Cov}_a(q(a),\, V_i^{(0)}(a))`. +All of these are scalars computed directly from the precomputed potential +:math:`\phi_i` and the charge statistics. + +When decoys are drawn uniformly (:math:`p(a) = 1/Q`), the charges sum to zero +(D, E contribute :math:`-2`; K, R contribute :math:`+2`), giving +:math:`\bar{q} = 0` and :math:`\sigma_q^2 = 4/Q`. + +*Pair decoy types* (mutational, contact, pseudo-configurational) depend on two +amino-acid indices and share a bilinear structure. Each correction can be written +as + +.. math:: + + \delta V_{ij}^{\mathrm{elec}}(a,b) + = + \mathbf{f}_i(a)^\top \, \mathbf{A}_{ij}^{\mathrm{elec}} \, \mathbf{f}_j(b), + +where :math:`\mathbf{f}_i(a)` is a small feature vector that depends only on +the amino-acid type (dimension 2: a constant and a charge), and +:math:`\mathbf{A}_{ij}^{\mathrm{elec}}` is a :math:`(2 \times 2)` coefficient +matrix that depends on the geometry and native environment at the contact. The +feature vectors and coefficient matrices for each decoy type are: + +.. list-table:: + :header-rows: 1 + :widths: 20 20 20 40 + + * - Decoy type + - :math:`\mathbf{f}_i(a)` + - :math:`\mathbf{f}_j(b)` + - :math:`\mathbf{A}_{ij}^{\mathrm{elec}}` + * - Mutational + - :math:`[1,\; \delta q_i(a)]^\top` + - :math:`[1,\; \delta q_j(b)]^\top` + - :math:`\begin{bmatrix} 0 & -\phi_j \\ -\phi_i & -\Gamma^{\mathrm{elec}}_{ij} \end{bmatrix}` + * - Contact + - :math:`[1,\; q(a)]^\top` + - :math:`[1,\; q(b)]^\top` + - :math:`\begin{bmatrix} q_i^N q_j^N\,\Gamma^{\mathrm{elec}}_{ij} & 0 \\ 0 & -\Gamma^{\mathrm{elec}}_{ij} \end{bmatrix}` + * - Pseudo-config. + - :math:`[1,\; q(a)]^\top` + - :math:`[1,\; q(b)]^\top` + - :math:`\begin{bmatrix} c_{00} & c_{01} \\ c_{10} & c_{11} \end{bmatrix}` + +where :math:`\delta q_i(a) = q(a) - q_i^N` as before, and the :math:`c` +coefficients are those defined in the pseudo-configurational section above. + +As a quick verification, expanding the mutational case gives +:math:`\mathbf{f}_i^\top \mathbf{A} \mathbf{f}_j = 1 \cdot (-\phi_j) \cdot \delta q_j + \delta q_i \cdot (-\phi_i) \cdot 1 + \delta q_i \cdot (-\Gamma^{\mathrm{elec}}_{ij}) \cdot \delta q_j`, +which recovers the three-term formula derived earlier. + +This bilinear structure lets us compute the exact mean and variance of the +correction using only :math:`(2 \times 2)` matrix operations, because decoy +amino acids :math:`a` and :math:`b` are drawn independently. + + +Step 1: Feature moments +"""""""""""""""""""""""" + +The decoy amino acids :math:`a` and :math:`b` are drawn from a distribution +(typically uniform over the :math:`Q` types), so the feature vectors become +random variables. We need their first and second moments. + +**First moments** (means): + +.. math:: + + \mathbf{m}_i = \mathbb{E}_a[\mathbf{f}_i(a)], + \qquad + \mathbf{m}_j = \mathbb{E}_b[\mathbf{f}_j(b)]. + +For mutational decoys with +:math:`\mathbf{f}_i(a) = [1,\; \delta q_i(a)]^\top`: +:math:`\mathbf{m}_i = [1,\; \bar{q} - q_i^N]^\top`, where +:math:`\bar{q} = \sum_a p(a)\,q(a)` is the mean charge under the amino-acid +frequency distribution :math:`p(a)`. + +**Second moments** (uncentered): + +.. math:: + + \mathbf{M}_i = \mathbb{E}_a[\mathbf{f}_i(a)\,\mathbf{f}_i(a)^\top], + \qquad + \mathbf{M}_j = \mathbb{E}_b[\mathbf{f}_j(b)\,\mathbf{f}_j(b)^\top]. + +Continuing the mutational example: + +.. math:: + + \mathbf{M}_i + = + \begin{bmatrix} + 1 & \bar{q} - q_i^N \\ + \bar{q} - q_i^N & \overline{q^2} - 2q_i^N\bar{q} + (q_i^N)^2 + \end{bmatrix}, + +where :math:`\overline{q^2} = \sum_a p(a)\,q(a)^2` is the second moment of the +charge. The :math:`(2,2)` entry is +:math:`\mathbb{E}[\delta q_i(a)^2] = \overline{q^2} - 2q_i^N\bar{q} + (q_i^N)^2`. + + +Step 2: Mean of the correction +""""""""""""""""""""""""""""""" + +Because :math:`a` and :math:`b` are drawn independently, the expectation of the +bilinear form factors cleanly: + +.. math:: + + \mu_{ij}^{\mathrm{elec}} + = + \mathbb{E}_{a,b}\!\left[\mathbf{f}_i(a)^\top \mathbf{A}_{ij}^{\mathrm{elec}}\, \mathbf{f}_j(b)\right] + = + \mathbf{m}_i^\top \, \mathbf{A}_{ij}^{\mathrm{elec}} \, \mathbf{m}_j. + +This is a single scalar computed from a :math:`(2 \times 2)` matrix sandwiched +between two 2-vectors. + + +Step 3: Variance of the correction +""""""""""""""""""""""""""""""""""" + +For the variance, we need :math:`\mathbb{E}[(\delta V_{ij}^{\mathrm{elec}})^2]`. +Squaring the bilinear form: + +.. math:: + + (\delta V_{ij}^{\mathrm{elec}})^2 + = + (\mathbf{f}_i^\top \mathbf{A}_{ij}^{\mathrm{elec}} \mathbf{f}_j)\, + (\mathbf{f}_j^\top \mathbf{A}_{ij}^{\mathrm{elec}\top} \mathbf{f}_i) + = + \mathbf{f}_i^\top \mathbf{A}_{ij}^{\mathrm{elec}}\, + \mathbf{f}_j \mathbf{f}_j^\top\, + \mathbf{A}_{ij}^{\mathrm{elec}\top} \mathbf{f}_i. + +Taking the expectation over :math:`b` first replaces +:math:`\mathbf{f}_j \mathbf{f}_j^\top` with :math:`\mathbf{M}_j`: + +.. math:: + + \mathbb{E}_b\!\left[(\delta V_{ij}^{\mathrm{elec}})^2\right] + = + \mathbf{f}_i^\top \mathbf{A}_{ij}^{\mathrm{elec}}\, \mathbf{M}_j\, \mathbf{A}_{ij}^{\mathrm{elec}\top} \mathbf{f}_i. + +This is now a quadratic form :math:`\mathbf{f}_i^\top \mathbf{B} \, \mathbf{f}_i` +where :math:`\mathbf{B} = \mathbf{A}_{ij}^{\mathrm{elec}}\, \mathbf{M}_j\, \mathbf{A}_{ij}^{\mathrm{elec}\top}`. +Using the standard identity +:math:`\mathbb{E}[\mathbf{f}^\top \mathbf{B} \, \mathbf{f}] = \operatorname{tr}(\mathbf{B}\,\mathbb{E}[\mathbf{f}\mathbf{f}^\top])`, +the expectation over :math:`a` gives: + +.. math:: + + \mathbb{E}[(\delta V_{ij}^{\mathrm{elec}})^2] + = + \operatorname{tr}\!\left( + \mathbf{A}_{ij}^{\mathrm{elec}}\, \mathbf{M}_j\, \mathbf{A}_{ij}^{\mathrm{elec}\top}\, \mathbf{M}_i + \right). + +The variance of the correction is therefore: + +.. math:: + + \sigma_{ij}^{2,\mathrm{elec}} + = + \operatorname{tr}\!\left( + \mathbf{A}_{ij}^{\mathrm{elec}}\, \mathbf{M}_j\, \mathbf{A}_{ij}^{\mathrm{elec}\top}\, \mathbf{M}_i + \right) + - + (\mu_{ij}^{\mathrm{elec}})^2. + +All matrices involved are :math:`(2 \times 2)`. + + +Step 4: Covariance with the base energy +"""""""""""""""""""""""""""""""""""""""" + +The total decoy energy is +:math:`V_{ij}^{\mathrm{tot}} = V_{ij}^{(0)} + \delta V_{ij}^{\mathrm{elec}}`, +so its variance decomposes as: + +.. math:: + + \mathrm{Var}(V_{ij}^{\mathrm{tot}}) + = + \sigma_{ij}^{2,(0)} + + + \sigma_{ij}^{2,\mathrm{elec}} + + + 2\,\mathrm{Cov}_{ij}^{(0,\mathrm{elec})}. + +The first term is already computed by the sparse decoy fluctuation code. The +second was derived above. The remaining piece is the cross-covariance between the +base Potts energy and the electrostatic correction. + +Define the cross-moment matrix: + +.. math:: + + \mathbf{T}_{ij} + = + \mathbb{E}_{a,b}\!\left[ + V_{ij}^{(0)}(a,b)\, + \mathbf{f}_i(a)\,\mathbf{f}_j(b)^\top + \right]. + +This :math:`(2 \times 2)` matrix captures how the base energy correlates with +the charge features. In practice it is computed by a weighted average over the +:math:`Q` amino-acid types. Using this: + +.. math:: + + \mathrm{Cov}_{ij}^{(0,\mathrm{elec})} + = + \operatorname{tr}(\mathbf{A}_{ij}^{\mathrm{elec}\top} \, \mathbf{T}_{ij}) + - + \mu_{ij}^{(0)} \, \mu_{ij}^{\mathrm{elec}}, + +where :math:`\mu_{ij}^{(0)} = \mathbb{E}[V_{ij}^{(0)}(a,b)]` is the mean base +decoy energy. + + +Step 5: Corrected frustration index +"""""""""""""""""""""""""""""""""""" + +Putting it all together: + +.. math:: + + F_{ij} + = + -\frac{\mu_{ij}^{(0)} + \mu_{ij}^{\mathrm{elec}}} + {\sqrt{ + \sigma_{ij}^{2,(0)} + + + \sigma_{ij}^{2,\mathrm{elec}} + + + 2\,\mathrm{Cov}_{ij}^{(0,\mathrm{elec})} + }}. + +Every quantity is computed exactly from the precomputed electrostatic data and +the sparse Potts model. diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index 522497b8..2f2c5199 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -77,11 +77,16 @@ def native_energy(self,sequence:str = None,ignore_couplings_of_gaps:bool=False,i sequence=self.sequence else: if getattr(self, 'sparse_potts_model', None) is not None: - return frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) + energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) + if getattr(self, '_elec_data', None) is not None: + energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) + return energy return frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) if not self._native_energy: if getattr(self, 'sparse_potts_model', None) is not None: self._native_energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) + if getattr(self, '_elec_data', None) is not None: + self._native_energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) else: self._native_energy=frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) energy_value=self._native_energy @@ -164,6 +169,8 @@ def couplings_energy(self, sequence:str = None,ignore_couplings_of_gaps:bool = F sequence=self.sequence if getattr(self, 'sparse_potts_model', None) is not None: couplings_energy=frustration.compute_couplings_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps) + if getattr(self, '_elec_data', None) is not None: + couplings_energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) else: couplings_energy=frustration.compute_couplings_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps) return couplings_energy @@ -177,7 +184,7 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: sequence : str The amino acid sequence of the protein. If no sequence is provided as input, the original protein sequence of the protein structure object is used for the energy calculation. kind : str - Kind of decoys generated. Options: "singleresidue," "mutational," "configurational," and "contact." + Kind of decoys generated. Options: "singleresidue," "mutational," "pseudoconfigurational," and "contact." mask : np.array A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. @@ -194,16 +201,25 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: mask=self.mask # Use sparse path when available _use_sparse = getattr(self, 'sparse_potts_model', None) is not None + _elec_data = getattr(self, '_elec_data', None) if _use_sparse: if kind == 'singleresidue': fluctuation = frustration.compute_singleresidue_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) + if _elec_data is not None: + fluctuation = frustration.apply_elec_correction_singleresidue(fluctuation, _elec_data) elif kind == 'mutational': fluctuation = frustration.compute_mutational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) - elif kind == 'configurational': + if _elec_data is not None: + fluctuation = frustration.apply_elec_correction_mutational(fluctuation, self.sparse_potts_model, _elec_data) + elif kind == 'pseudoconfigurational': mask_mean = self.mask.mean() - fluctuation = frustration.compute_configurational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model, mask_mean) + fluctuation = frustration.compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model, mask_mean) + if _elec_data is not None: + fluctuation = frustration.apply_elec_correction_pseudoconfigurational(fluctuation, self.sparse_potts_model, _elec_data) elif kind == 'contact': fluctuation = frustration.compute_contact_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) + if _elec_data is not None: + fluctuation = frustration.apply_elec_correction_contact(fluctuation, self.sparse_potts_model, _elec_data) else: raise Exception("Wrong kind of decoy generation selected") else: @@ -211,8 +227,8 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: fluctuation = frustration.compute_singleresidue_decoy_energy_fluctuation(sequence, self.potts_model, mask) elif kind == 'mutational': fluctuation = frustration.compute_mutational_decoy_energy_fluctuation(sequence, self.potts_model, mask) - elif kind == 'configurational': - fluctuation = frustration.compute_configurational_decoy_energy_fluctuation(sequence, self.potts_model, mask) + elif kind == 'pseudoconfigurational': + fluctuation = frustration.compute_pseudoconfigurational_decoy_energy_fluctuation(sequence, self.potts_model, mask) elif kind == 'contact': fluctuation = frustration.compute_contact_decoy_energy_fluctuation(sequence, self.potts_model, mask) else: @@ -229,7 +245,7 @@ def decoy_energy(self, kind:str = 'singleresidue',sequence: str =None) ->np.arra sequence : str The amino acid sequence of the protein. The sequence is assumed to be in one-letter code. Gaps are represented as '-'. The length of the sequence (L) should match the dimensions of the Potts model. kind : str - Kind of decoys generated. Options: "singleresidue," "mutational," "configurational," and "contact." + Kind of decoys generated. Options: "singleresidue," "mutational," "pseudoconfigurational," and "contact." Returns ------- @@ -272,7 +288,7 @@ def frustration(self, sequence:str = None, kind:str = 'singleresidue', mask:np.a sequence : str The amino acid sequence of the protein. The sequence is assumed to be in one-letter code. Gaps are represented as '-'. The length of the sequence (L) should match the dimensions of the Potts model. kind : str - Kind of decoys generated. Options: "singleresidue," "mutational," "configurational," and "contact." + Kind of decoys generated. Options: "singleresidue," "mutational," "pseudoconfigurational," "configurational," and "contact." mask : np.array A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. aa_freq: np.array @@ -293,10 +309,10 @@ def frustration(self, sequence:str = None, kind:str = 'singleresidue', mask:np.a aa_freq = self.aa_freq frustration_values=frustration.compute_single_frustration(decoy_fluctuation, aa_freq, correction) return frustration_values - elif kind in ['mutational', 'configurational', 'contact']: - if kind == 'configurational' and 'configurational_frustration' in dir(self): - #TODO: Correct this function for different aa_freq than WT - return self.configurational_frustration(None, correction) + elif kind == 'configurational' and 'configurational_frustration' in dir(self): + #TODO: Correct this function for different aa_freq than WT + return self.configurational_frustration(None, correction) + elif kind in ['mutational', 'pseudoconfigurational', 'contact']: if aa_freq is None: aa_freq = self.contact_freq # Sparse decoy fluctuation has shape (N_contacts, 21, 21) — use sparse pair frustration, then densify @@ -322,7 +338,7 @@ def plot_decoy_energy(self, sequence:str = None, kind:str = 'singleresidue', met sequence : str The amino acid sequence of the protein. The sequence is assumed to be in one-letter code. Gaps are represented as '-'. The length of the sequence (L) should match the dimensions of the Potts model. kind : str - Kind of decoys generated. Options: "singleresidue," "mutational," "configurational," and "contact." + Kind of decoys generated. Options: "singleresidue," "mutational," "pseudoconfigurational," and "contact." method : str Options: "clustermap", "heatmap" """ @@ -364,7 +380,7 @@ def vmd(self, sequence: str = None, single:Union[str,np.array] = 'singleresidue' sequence : str The amino acid sequence of the protein. The sequence is assumed to be in one-letter code. Gaps are represented as '-'. The length of the sequence (L) should match the dimensions of the Potts model. pair : str - Kind of pair frustration calculated. Options: "mutational," "configurational," and "contact." + Kind of pair frustration calculated. Options: "mutational," "pseudoconfigurational," "configurational," and "contact." aa_freq: np.array Array of frequencies of all 21 possible amino acids within sequence max_connections : int @@ -397,7 +413,7 @@ def view_pair_frustration(self, sequence:str = None, pair:str = 'mutational', aa sequence : str The amino acid sequence of the protein. The sequence is assumed to be in one-letter code. Gaps are represented as '-'. The length of the sequence (L) should match the dimensions of the Potts model. pair : str - Kind of pair frustration calculated. Options: "mutational," "configurational," and "contact." + Kind of pair frustration calculated. Options: "mutational," "pseudoconfigurational," "configurational," and "contact." aa_freq: np.array Array of frequencies of all 21 possible amino acids within sequence """ @@ -484,7 +500,7 @@ def generate_frustration_pair_distribution(self,sequence: str =None, kind:str =" """ Calculates frustration pair distributions. This helps identify spatial proximity of similarly frustrated residues or contacts from one another. - For mutational, configurational, and contact frustration pair distributions, the distances between midpoints of Cb-Cb (or Ca in the case of glycine) + For mutational, pseudoconfigurational, configurational, and contact frustration pair distributions, the distances between midpoints of Cb-Cb (or Ca in the case of glycine) atom pairs are measured. For single residue frustration, the distances of Cb (or Ca in the case of glycine) atoms are measured. @@ -495,7 +511,7 @@ def generate_frustration_pair_distribution(self,sequence: str =None, kind:str =" aa_freq : np.array Array of frequencies of all 21 possible amino acids within sequence kind : str - Kind of decoys generated. Options: "singleresidue," "mutational," "configurational," and "contact." + Kind of decoys generated. Options: "singleresidue," "mutational," "pseudoconfigurational," "configurational," and "contact." bins : int Number of bins maximum_shell_radius : int @@ -526,7 +542,7 @@ def generate_frustration_pair_distribution(self,sequence: str =None, kind:str =" if kind=="singleresidue": sel_frustration = np.column_stack((residue_cb_coordinates,np.expand_dims(frustration_values, axis=1))) - elif kind in ["configurational","mutational"]: + elif kind in ["configurational","pseudoconfigurational","mutational"]: i,j=np.meshgrid(range(0,len(self.sequence)),range(0,len(self.sequence))) midpoint_coordinates=(residue_cb_coordinates[i.flatten(),:]+ residue_cb_coordinates[j.flatten(),:])/2 sel_frustration = np.column_stack((midpoint_coordinates, frustration_values.ravel())) @@ -580,7 +596,7 @@ def total_frustration(self, n_decoys: int Number of sequence decoys to create config_decoys: bool - If True, use the configurational decoys approximation, shuffling index positions for configurational decoys energy calculation. If False, mutational decoys. + If True, use the pseudoconfigurational decoys approximation, shuffling index positions for pseudoconfigurational decoys energy calculation. If False, mutational decoys. msa_mask: np.array Extra mask to use a Multiple Sequence Alignment that do not cover completely the reference PDB fragment_pos: np.array diff --git a/frustratometer/frustration/__init__.py b/frustratometer/frustration/__init__.py index 6e85b95e..9074192c 100644 --- a/frustratometer/frustration/__init__.py +++ b/frustratometer/frustration/__init__.py @@ -10,7 +10,7 @@ __all__ = ['compute_mask', 'compute_native_energy', 'compute_fields_energy', 'compute_couplings_energy', 'compute_sequences_energy', 'compute_singleresidue_decoy_energy_fluctuation', - 'compute_mutational_decoy_energy_fluctuation', 'compute_configurational_decoy_energy_fluctuation', + 'compute_mutational_decoy_energy_fluctuation', 'compute_pseudoconfigurational_decoy_energy_fluctuation', 'compute_contact_decoy_energy_fluctuation', 'compute_decoy_energy', 'compute_aa_freq', 'compute_contact_freq', 'compute_single_frustration', 'compute_pair_frustration', 'compute_scores', 'compute_roc', 'compute_auc', 'plot_roc', 'plot_singleresidue_decoy_energy', 'write_tcl_script', @@ -30,7 +30,15 @@ 'compute_sequences_energy_sparse', 'compute_singleresidue_decoy_energy_fluctuation_sparse', 'compute_mutational_decoy_energy_fluctuation_sparse', - 'compute_configurational_decoy_energy_fluctuation_sparse', + 'compute_pseudoconfigurational_decoy_energy_fluctuation_sparse', 'compute_contact_decoy_energy_fluctuation_sparse', 'compute_pair_frustration_sparse', - 'sparse_frustration_to_dense'] + 'sparse_frustration_to_dense', + 'compute_elec_indicator', + 'build_elec_data', + 'compute_native_energy_elec', + 'apply_elec_correction_singleresidue', + 'apply_elec_correction_mutational', + 'apply_elec_correction_contact', + 'apply_elec_correction_pseudoconfigurational', + ] diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index 25ba72e8..1cb20713 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -490,12 +490,12 @@ def compute_mutational_decoy_energy_fluctuation(seq: str, return decoy_energy2 -def compute_configurational_decoy_energy_fluctuation(seq: str, +def compute_pseudoconfigurational_decoy_energy_fluctuation(seq: str, potts_model: dict, mask: np.array, ) -> np.array: r""" Computes a (LxLx21x21) matrix for a sequence of length L. Matrix[i,j] describes all possible changes in energy upon mutating and altering the - local densities of residue i and j simultaneously. + local densities of residue i and j simultaneously (pseudo-configurational approximation). .. math:: \Delta H_{ij} = H_i - H_{i'} + H_{j}-H_{j'} + J_{ij} -J_{ij'} + J_{i'j'} - J_{i'j} + \\sum_k {J_{ik} - J_{i'k} + J_{jk} -J_{j'k}} @@ -522,8 +522,8 @@ def compute_configurational_decoy_energy_fluctuation(seq: str, 'J': np.random.rand(20, 20, 20, 20) # Random couplings } >>> mask = np.ones((len(seq), len(seq)), dtype=bool) # Include all pairs - >>> decoy_energy2 = compute_configurational_decoy_energy_fluctuation(seq, potts_model, mask) - >>> print(f"Matrix of Contact Configurational Decoy Energy Fluctuations: "); print(decoy_energy2) + >>> decoy_energy2 = compute_pseudoconfigurational_decoy_energy_fluctuation(seq, potts_model, mask) + >>> print(f"Matrix of Pseudo-configurational Decoy Energy Fluctuations: "); print(decoy_energy2) >>> print(f"Matrix Size: "); print(shape(decoy_energy2)) Notes @@ -608,7 +608,7 @@ def compute_decoy_energy(seq: str, potts_model: dict, mask: np.array, kind='sing mask : np.array A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. kind : str - Kind of decoys generated. Options: "singleresidue," "mutational," "configurational," and "contact." + Kind of decoys generated. Options: "singleresidue," "mutational," "pseudoconfigurational," and "contact." Returns ------- decoy_energy: np.array @@ -641,8 +641,8 @@ def compute_decoy_energy(seq: str, potts_model: dict, mask: np.array, kind='sing decoy_energy=native_energy + compute_singleresidue_decoy_energy_fluctuation(seq, potts_model, mask) elif kind == 'mutational': decoy_energy=native_energy + compute_mutational_decoy_energy_fluctuation(seq, potts_model, mask) - elif kind == 'configurational': - decoy_energy=native_energy + compute_configurational_decoy_energy_fluctuation(seq, potts_model, mask) + elif kind == 'pseudoconfigurational': + decoy_energy=native_energy + compute_pseudoconfigurational_decoy_energy_fluctuation(seq, potts_model, mask) elif kind == 'contact': decoy_energy=native_energy + compute_contact_decoy_energy_fluctuation(seq, potts_model, mask) return decoy_energy @@ -737,7 +737,7 @@ def compute_pair_frustration(decoy_fluctuation, Returns ------- contact_frustration: np.array - LxL array featuring pair frustration indices (mutational or configurational frustration, depending on + LxL array featuring pair frustration indices (mutational or pseudoconfigurational frustration, depending on decoy_fluctuation matrix provided) """ if contact_freq is None: @@ -910,7 +910,7 @@ def write_tcl_script(pdb_file: Union[Path,str], chain: str, mask: np.array, dist single_frustration : np.array Array containing single residue frustration index values pair_frustration : np.array - Array containing pair (ex. configurational, mutational, contact) frustration index values + Array containing pair (ex. pseudoconfigurational, mutational, contact) frustration index values tcl_script : Path or str Output tcl script file with static structure max_connections : int @@ -1246,7 +1246,7 @@ def compute_fragment_total_decoy_energy(decoy_seqs: list, split_couplings_and_fields: bool Separate output into coupling and local fields contribution to energy. config_decoys: bool - If True, use the configurational decoys approximation, shuffling index positions for configurational decoys energy calculation. If False, mutational decoys. + If True, use the pseudoconfigurational decoys approximation, shuffling index positions for pseudoconfigurational decoys energy calculation. If False, mutational decoys. msa_mask: np.array Extra mask to use a Multiple Sequence Alignment that do not cover completely the reference PDB @@ -1322,7 +1322,7 @@ def compute_total_frustration(seq, n_decoys: int Number of sequence decoys to create config_decoys: bool - If True, use the configurational decoys approximation, shuffling index positions for configurational decoys energy calculation. If False, mutational decoys. + If True, use the pseudoconfigurational decoys approximation, shuffling index positions for pseudoconfigurational decoys energy calculation. If False, mutational decoys. msa_mask: np.array Extra mask to use a Multiple Sequence Alignment that do not cover completely the reference PDB fragment_pos: np.array @@ -1428,7 +1428,7 @@ def compute_decoy_h_J(decoy_seqs: list, mask : np.array A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. config_decoys: bool - If True, use the configurational decoys approximation, shuffling index positions for configurational decoys energy calculation. If False, mutational decoys. + If True, use the pseudoconfigurational decoys approximation, shuffling index positions for pseudoconfigurational decoys energy calculation. If False, mutational decoys. Returns ------- @@ -1559,7 +1559,7 @@ def compute_energy_sliding_window(seq: str, ndecoys: int Number of decoy sequences to use config_decoys: bool - If True, use the configurational decoys approximation, shuffling index positions for configurational decoys energy calculation. If False, mutational decoys. + If True, use the pseudoconfigurational decoys approximation, shuffling index positions for pseudoconfigurational decoys energy calculation. If False, mutational decoys. Returns ------- @@ -1990,7 +1990,7 @@ def compute_mutational_decoy_energy_fluctuation_sparse(seq: str, return decoy_energy -def compute_configurational_decoy_energy_fluctuation_sparse(seq: str, +def compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(seq: str, sparse_potts_model: dict, mask_mean: float) -> np.ndarray: """ @@ -2005,7 +2005,7 @@ def compute_configurational_decoy_energy_fluctuation_sparse(seq: str, sparse_potts_model : dict Sparse Potts model. mask_mean : float - Mean of the original dense mask, used as weight for configurational decoys. + Mean of the original dense mask, used as weight for pseudoconfigurational decoys. Returns ------- @@ -2143,4 +2143,305 @@ def sparse_frustration_to_dense(frustration_values: np.ndarray, dense[contact_i, contact_j] = frustration_values return dense + +def _build_charges_array(): + """ + Build the (21,) charge vector in the DCA alphabet order. + + Returns + ------- + charges : np.ndarray (21,) + Charge of each amino acid in ``_AA`` order. D, E = -1; K, R = +1. + """ + charges = np.zeros(21) + for idx, aa in enumerate(_AA): + if aa in 'DE': + charges[idx] = -1.0 + elif aa in 'KR': + charges[idx] = 1.0 + return charges + + +# Module-level constant +_CHARGES = _build_charges_array() +_Q_VAR = (_CHARGES ** 2).sum() / 21 # Var(q) under uniform freq = 4/21 + + +def compute_elec_indicator(distance_matrix: np.ndarray, + k_electrostatics: float = 17.3636, + screening_length: float = 10.0) -> np.ndarray: + """ + Compute the electrostatic indicator matrix (Debye-Hückel screening). + + .. math:: + \\text{indicator}(i,j) = -k_{\\text{elec}} \\frac{\\exp(-d_{ij}/\\lambda)}{d_{ij}} + + Parameters + ---------- + distance_matrix : np.ndarray (L, L) + Distance matrix between residues. + k_electrostatics : float + Electrostatic coupling coefficient (kJ/mol). Default 17.3636. + screening_length : float + Debye-Hückel screening length (Angstrom). Default 10.0. + + Returns + ------- + indicator : np.ndarray (L, L) + Electrostatic indicator. Negative for all pair distances > 0. + """ + with np.errstate(divide='ignore', invalid='ignore'): + indicator = -k_electrostatics * np.exp(-distance_matrix / screening_length) / distance_matrix + indicator[np.isnan(indicator)] = 0.0 + indicator[np.isinf(indicator)] = 0.0 + return indicator + + +def build_elec_data(distance_matrix: np.ndarray, + mask: np.ndarray, + sequence: str, + sparse_potts_model: dict, + k_electrostatics: float = 17.3636, + screening_length: float = 10.0, + min_sequence_separation_electrostatics: int = 1) -> dict: + """ + Precompute all electrostatic data needed for sparse corrections. + + Parameters + ---------- + distance_matrix : np.ndarray (L, L) + Distance matrix between residues. + mask : np.ndarray (L, L) + Contact mask (the mask used for frustration, may differ from + the electrostatic mask). + sequence : str + Amino acid sequence (length L). + sparse_potts_model : dict + Sparse Potts model. + k_electrostatics : float + Electrostatic coupling coefficient. + screening_length : float + Screening length (Angstrom). + min_sequence_separation_electrostatics : int + Minimum sequence separation for electrostatic interactions. + + Returns + ------- + elec_data : dict + Dictionary with keys: + - 'charges': (21,) charge array + - 'q_var': scalar, Var(q) under uniform frequency + - 'q_native': (L,) native charges + - 'indicator': (L, L) full indicator matrix + - 'indicator_at_contacts': (N_contacts,) indicator values + - 'phi': (L,) indicator * mask @ q_native + - 'phi_raw': (L,) indicator @ q_native (unmasked, for pseudoconfigurational) + - 'mask_at_contacts': (N_contacts,) mask values at contacts + - 'mask_mean': scalar, mean of mask + """ + seq_index = np.array([_AA.find(aa) for aa in sequence]) + L = len(seq_index) + charges = _CHARGES + q_native = charges[seq_index] + + # Full indicator matrix + indicator = compute_elec_indicator(distance_matrix, k_electrostatics, screening_length) + + # Apply electrostatic sequence separation + elec_mask = compute_mask(distance_matrix, + maximum_contact_distance=None, + minimum_sequence_separation=min_sequence_separation_electrostatics) + indicator = indicator * elec_mask + + ci = sparse_potts_model['contact_i'] + cj = sparse_potts_model['contact_j'] + + # phi vectors + indicator_masked = indicator * mask + phi = indicator_masked @ q_native # (L,) + phi_raw = indicator @ q_native # (L,) — unmasked + + return { + 'charges': charges, + 'q_var': _Q_VAR, + 'q_native': q_native, + 'indicator': indicator, + 'indicator_at_contacts': indicator[ci, cj], + 'phi': phi, + 'phi_raw': phi_raw, + 'mask_at_contacts': mask[ci, cj].astype(float), + 'mask_mean': float(mask.mean()), + } + + +def compute_native_energy_elec(sequence: str, + elec_data: dict, + mask: np.ndarray) -> float: + """ + Compute the electrostatic contribution to the native energy. + + Parameters + ---------- + sequence : str + Amino acid sequence. + elec_data : dict + Electrostatic data from ``build_elec_data``. + mask : np.ndarray (L, L) + Contact mask. + + Returns + ------- + energy : float + """ + q_native = elec_data['q_native'] + indicator = elec_data['indicator'] + energy = -0.5 * (indicator * mask * np.outer(q_native, q_native)).sum() + return energy + + +def apply_elec_correction_singleresidue(decoy_fluctuation: np.ndarray, + elec_data: dict) -> np.ndarray: + """ + Apply electrostatic correction to single-residue decoy fluctuation. + + Parameters + ---------- + decoy_fluctuation : np.ndarray (L, 21) + Decoy energy fluctuation from Potts-only sparse computation. + elec_data : dict + Electrostatic data from ``build_elec_data``. + + Returns + ------- + corrected : np.ndarray (L, 21) + """ + charges = elec_data['charges'] + q_native = elec_data['q_native'] + phi = elec_data['phi'] + + correction = -(charges[np.newaxis, :] - q_native[:, np.newaxis]) * phi[:, np.newaxis] + return decoy_fluctuation + correction + + +def apply_elec_correction_mutational(decoy_fluctuation: np.ndarray, + sparse_potts_model: dict, + elec_data: dict) -> np.ndarray: + """ + Apply electrostatic correction to mutational decoy fluctuation. + + Parameters + ---------- + decoy_fluctuation : np.ndarray (N_contacts, 21, 21) + Decoy energy fluctuation from Potts-only sparse computation. + sparse_potts_model : dict + Sparse Potts model. + elec_data : dict + Electrostatic data from ``build_elec_data``. + + Returns + ------- + corrected : np.ndarray (N_contacts, 21, 21) + """ + charges = elec_data['charges'] + q_native = elec_data['q_native'] + phi = elec_data['phi'] + ind_vals = elec_data['indicator_at_contacts'] + ci = sparse_potts_model['contact_i'] + cj = sparse_potts_model['contact_j'] + + qn1 = q_native[ci] + qn2 = q_native[cj] + + dq_a = charges[np.newaxis, :] - qn1[:, np.newaxis] # (N, 21) + dq_b = charges[np.newaxis, :] - qn2[:, np.newaxis] # (N, 21) + + correction = -(dq_a * phi[ci][:, np.newaxis])[:, :, np.newaxis] + correction = correction - (dq_b * phi[cj][:, np.newaxis])[:, np.newaxis, :] + correction = correction - ind_vals[:, np.newaxis, np.newaxis] * dq_a[:, :, np.newaxis] * dq_b[:, np.newaxis, :] + + return decoy_fluctuation + correction + + +def apply_elec_correction_contact(decoy_fluctuation: np.ndarray, + sparse_potts_model: dict, + elec_data: dict) -> np.ndarray: + """ + Apply electrostatic correction to contact decoy fluctuation. + + Parameters + ---------- + decoy_fluctuation : np.ndarray (N_contacts, 21, 21) + Decoy energy fluctuation from Potts-only sparse computation. + sparse_potts_model : dict + Sparse Potts model. + elec_data : dict + Electrostatic data from ``build_elec_data``. + + Returns + ------- + corrected : np.ndarray (N_contacts, 21, 21) + """ + charges = elec_data['charges'] + q_native = elec_data['q_native'] + ind_vals = elec_data['indicator_at_contacts'] + ci = sparse_potts_model['contact_i'] + cj = sparse_potts_model['contact_j'] + + qn1 = q_native[ci] + qn2 = q_native[cj] + + correction = ind_vals[:, np.newaxis, np.newaxis] * ( + (qn1 * qn2)[:, np.newaxis, np.newaxis] + - charges[np.newaxis, :, np.newaxis] * charges[np.newaxis, np.newaxis, :] + ) + + return decoy_fluctuation + correction + + +def apply_elec_correction_pseudoconfigurational(decoy_fluctuation: np.ndarray, + sparse_potts_model: dict, + elec_data: dict) -> np.ndarray: + """ + Apply electrostatic correction to pseudo-configurational decoy fluctuation. + + Parameters + ---------- + decoy_fluctuation : np.ndarray (N_contacts, 21, 21) + Decoy energy fluctuation from Potts-only sparse computation. + sparse_potts_model : dict + Sparse Potts model. + elec_data : dict + Electrostatic data from ``build_elec_data``. + + Returns + ------- + corrected : np.ndarray (N_contacts, 21, 21) + """ + charges = elec_data['charges'] + q_native = elec_data['q_native'] + phi = elec_data['phi'] + phi_raw = elec_data['phi_raw'] + ind_vals = elec_data['indicator_at_contacts'] + mask_vals = elec_data['mask_at_contacts'] + mask_mean = elec_data['mask_mean'] + ci = sparse_potts_model['contact_i'] + cj = sparse_potts_model['contact_j'] + + qn1 = q_native[ci] + qn2 = q_native[cj] + + c00 = qn1 * phi[ci] + qn2 * phi[cj] - ind_vals * qn1 * qn2 * mask_vals + c10 = mask_mean * (ind_vals * qn2 - phi_raw[ci]) + c01 = mask_mean * (ind_vals * qn1 - phi_raw[cj]) + c11 = -ind_vals * mask_mean + + qa = charges[np.newaxis, :, np.newaxis] # (1, 21, 1) + qb = charges[np.newaxis, np.newaxis, :] # (1, 1, 21) + correction = (c00[:, np.newaxis, np.newaxis] + + c10[:, np.newaxis, np.newaxis] * qa + + c01[:, np.newaxis, np.newaxis] * qb + + c11[:, np.newaxis, np.newaxis] * qa * qb) + + return decoy_fluctuation + correction + \ No newline at end of file diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index a417c452..53aa3ee9 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -422,15 +422,29 @@ def test_expose_indicators(structure, k_electrostatics, min_sequence_separation_ from frustratometer.frustration.frustration import ( potts_model_dense_to_sparse, + compute_native_energy, compute_native_energy_sparse, compute_couplings_energy_sparse, + compute_singleresidue_decoy_energy_fluctuation, compute_singleresidue_decoy_energy_fluctuation_sparse, + compute_mutational_decoy_energy_fluctuation, compute_mutational_decoy_energy_fluctuation_sparse, - compute_configurational_decoy_energy_fluctuation_sparse, + compute_pseudoconfigurational_decoy_energy_fluctuation, + compute_pseudoconfigurational_decoy_energy_fluctuation_sparse, + compute_contact_decoy_energy_fluctuation, compute_contact_decoy_energy_fluctuation_sparse, compute_pair_frustration, compute_pair_frustration_sparse, sparse_frustration_to_dense, + compute_mask, + compute_elec_indicator, + build_elec_data, + compute_native_energy_elec, + apply_elec_correction_singleresidue, + apply_elec_correction_mutational, + apply_elec_correction_contact, + apply_elec_correction_pseudoconfigurational, + _CHARGES, ) # --- Sparse cross-validation fixtures (module-scoped, computed once) --- @@ -451,7 +465,7 @@ def dense_decoys_6u5e_density(awsem_6u5e_density): 'singleresidue': m.decoy_fluctuation(kind='singleresidue'), 'mutational': m.decoy_fluctuation(kind='mutational'), 'contact': m.decoy_fluctuation(kind='contact'), - 'configurational': m.decoy_fluctuation(kind='configurational'), + 'pseudoconfigurational': m.decoy_fluctuation(kind='pseudoconfigurational'), } # --- Sparse cross-validation tests --- @@ -473,7 +487,7 @@ def test_sparse_energy_matches_dense(fixture_name, awsem_6u5e, awsem_6u5e_densit np.testing.assert_allclose(dense_fields + compute_couplings_energy_sparse(model.sequence, spm), dense_native, rtol=1e-10) -@pytest.mark.parametrize("kind", ["singleresidue", "mutational", "contact", "configurational"]) +@pytest.mark.parametrize("kind", ["singleresidue", "mutational", "contact", "pseudoconfigurational"]) def test_sparse_decoy_matches_dense(kind, awsem_6u5e_density, sparse_6u5e_density, dense_decoys_6u5e_density): """Sparse decoy fluctuation must match dense for all four kinds.""" model = awsem_6u5e_density @@ -483,8 +497,8 @@ def test_sparse_decoy_matches_dense(kind, awsem_6u5e_density, sparse_6u5e_densit if kind == 'singleresidue': sparse = compute_singleresidue_decoy_energy_fluctuation_sparse(model.sequence, spm) np.testing.assert_allclose(sparse, dense, atol=1e-4) - elif kind == 'configurational': - sparse = compute_configurational_decoy_energy_fluctuation_sparse(model.sequence, spm, model.mask.mean()) + elif kind == 'pseudoconfigurational': + sparse = compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(model.sequence, spm, model.mask.mean()) ci, cj = spm['contact_i'], spm['contact_j'] np.testing.assert_allclose(sparse, dense[ci, cj], atol=1e-4) else: @@ -515,5 +529,99 @@ def test_sparse_frustration_matches_dense(kind, awsem_6u5e_density, sparse_6u5e_ np.testing.assert_allclose(dense_from_sparse[ci, cj], dense_frust[ci, cj], atol=1e-4) +@pytest.fixture(scope="module") +def elec_setup(awsem_6u5e_density, sparse_6u5e_density): + """ + Build electrostatics test data from the real 6u5e model. + + Takes the k_elec=0 model, constructs J_elec using compute_elec_indicator + (same formula as build_elec_data), adds it to J to create 'combined' dense + Potts model. Then builds elec_data for the sparse path. + + Returns dict with: model, spm, elec_data, combined_potts, mask, k_elec. + """ + model = awsem_6u5e_density + spm = sparse_6u5e_density + mask = model.mask + k_elec = 4 * 4.184 # same value used in AWSEM test configs + screening_length = 10.0 + min_sep_elec = 1 + + # Build indicator (includes -k factor and elec_mask) + indicator = compute_elec_indicator(model.distance_matrix, k_elec, screening_length) + elec_mask = compute_mask(model.distance_matrix, + maximum_contact_distance=None, + minimum_sequence_separation=min_sep_elec) + indicator = indicator * elec_mask + + # Construct J_elec: indicator[i,j] * q_a * q_b + charges = _CHARGES + J_elec = indicator[:, :, np.newaxis, np.newaxis] * charges[np.newaxis, np.newaxis, :, np.newaxis] * charges[np.newaxis, np.newaxis, np.newaxis, :] + + # Combined dense Potts model (contact + electrostatics) + combined_potts = { + 'h': model.potts_model['h'].copy(), + 'J': model.potts_model['J'] + J_elec, + } + + # Build elec_data for sparse path + elec_data = build_elec_data(model.distance_matrix, mask, model.sequence, spm, + k_elec, screening_length, min_sep_elec) + + return { + 'model': model, + 'spm': spm, + 'elec_data': elec_data, + 'combined_potts': combined_potts, + 'mask': mask, + } + + +def test_elec_native_energy(elec_setup): + """Sparse native energy + electrostatic energy must match dense combined model.""" + s = elec_setup + model, spm, elec_data, mask = s['model'], s['spm'], s['elec_data'], s['mask'] + + dense_energy = compute_native_energy(model.sequence, s['combined_potts'], mask) + sparse_energy = compute_native_energy_sparse(model.sequence, spm) + elec_energy = compute_native_energy_elec(model.sequence, elec_data, mask) + + np.testing.assert_allclose(sparse_energy + elec_energy, dense_energy, rtol=1e-10) + + +@pytest.mark.parametrize("kind", ["singleresidue", "mutational", "contact", "pseudoconfigurational"]) +def test_elec_decoy_correction(kind, elec_setup): + """Sparse decoy + electrostatic correction must match dense combined decoy.""" + s = elec_setup + model, spm, elec_data, mask = s['model'], s['spm'], s['elec_data'], s['mask'] + combined_potts = s['combined_potts'] + seq = model.sequence + + # Dense decoy from combined (contact + elec) Potts model + if kind == 'singleresidue': + dense_decoy = compute_singleresidue_decoy_energy_fluctuation(seq, combined_potts, mask) + sparse_decoy = compute_singleresidue_decoy_energy_fluctuation_sparse(seq, spm) + corrected = apply_elec_correction_singleresidue(sparse_decoy, elec_data) + np.testing.assert_allclose(corrected, dense_decoy, atol=1e-4) + elif kind == 'mutational': + dense_decoy = compute_mutational_decoy_energy_fluctuation(seq, combined_potts, mask) + sparse_decoy = compute_mutational_decoy_energy_fluctuation_sparse(seq, spm) + corrected = apply_elec_correction_mutational(sparse_decoy, spm, elec_data) + ci, cj = spm['contact_i'], spm['contact_j'] + np.testing.assert_allclose(corrected, dense_decoy[ci, cj], atol=1e-4) + elif kind == 'contact': + dense_decoy = compute_contact_decoy_energy_fluctuation(seq, combined_potts, mask) + sparse_decoy = compute_contact_decoy_energy_fluctuation_sparse(seq, spm) + corrected = apply_elec_correction_contact(sparse_decoy, spm, elec_data) + ci, cj = spm['contact_i'], spm['contact_j'] + np.testing.assert_allclose(corrected, dense_decoy[ci, cj], atol=1e-4) + elif kind == 'pseudoconfigurational': + dense_decoy = compute_pseudoconfigurational_decoy_energy_fluctuation(seq, combined_potts, mask) + sparse_decoy = compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(seq, spm, mask.mean()) + corrected = apply_elec_correction_pseudoconfigurational(sparse_decoy, spm, elec_data) + ci, cj = spm['contact_i'], spm['contact_j'] + np.testing.assert_allclose(corrected, dense_decoy[ci, cj], atol=1e-4) + + if __name__ == "__main__": pytest.main() From 2748c7a28fc972d45ae784e7c62b80a4fc95afee Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Wed, 8 Apr 2026 01:48:01 -0500 Subject: [PATCH 10/28] Adds sparse methods to AWSEM --- frustratometer/classes/AWSEM.py | 256 ++++++++++++++-------- frustratometer/frustration/frustration.py | 6 +- tests/test_awsem_frustratometer.py | 189 ++++++++++++++-- tests/test_optimization.py | 2 +- 4 files changed, 342 insertions(+), 111 deletions(-) diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index eb7584fb..42e1e157 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -57,6 +57,7 @@ def __init__(self, pdb_structure: object, sequence: str =None, expose_indicator_functions: bool=False, + sparse: bool=True, **parameters)->object: """ Generate AWSEM object @@ -69,6 +70,9 @@ def __init__(self, The amino acid sequence of the protein. The sequence is assumed to be in one-letter code. expose_indicator_functions: bool If set to True, indicator functions of the contact and burial energy terms can be accessed by user. + sparse : bool + If True (default), build a sparse Potts model storing couplings only at contact positions, + avoiding the dense (N, N, Q, Q) meshgrid. If False, build the full dense representation. Returns ------- @@ -163,94 +167,182 @@ def __init__(self, theta = 0.25 * (1 + np.tanh(p.eta * (self.distance_matrix - p.r_min))) * (1 + np.tanh(p.eta * (p.r_max - self.distance_matrix))) thetaII = 0.25 * (1 + np.tanh(p.eta * (self.distance_matrix - p.r_minII))) * (1 + np.tanh(p.eta * (p.r_maxII - self.distance_matrix))) burial_indicator = np.tanh(p.burial_kappa * (rho_b - p.burial_ro_min)) + np.tanh(p.burial_kappa * (p.burial_ro_max - rho_b)) - direct_indicator = theta[:, :, np.newaxis, np.newaxis] - water_indicator = thetaII[:, :, np.newaxis, np.newaxis] * sigma_water[:, :, np.newaxis, np.newaxis] - protein_indicator = thetaII[:, :, np.newaxis, np.newaxis] * sigma_protein[:, :, np.newaxis, np.newaxis] - - if expose_indicator_functions: - self.indicators=[] - self.indicators.append(burial_indicator[:,0]) - self.indicators.append(burial_indicator[:,1]) - self.indicators.append(burial_indicator[:,2]) - - self.indicators.append(direct_indicator[:,:,0,0]*sequence_mask_contact) - self.indicators.append(protein_indicator[:,:,0,0]*sequence_mask_contact) - self.indicators.append(water_indicator[:,:,0,0]*sequence_mask_contact) - - self.gamma_array=[] - temp_burial_gamma=self.burial_gamma[self.aa_map_awsem_list] - temp_burial_gamma[0]=0 - temp_burial_gamma *= -0.5 * p.k_contact - self.gamma_array.append(temp_burial_gamma[:,0]) - self.gamma_array.append(temp_burial_gamma[:,1]) - self.gamma_array.append(temp_burial_gamma[:,2]) - - for contact_gamma in [self.direct_gamma, self.protein_gamma, self.water_gamma]: - temp_gamma = contact_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y].copy() - temp_gamma[0, :] = 0 - temp_gamma[:, 0] = 0 - temp_gamma *= -0.5 * self.k_contact - self.gamma_array.append(temp_gamma) + self._burial_indicator = burial_indicator + self._sigma_water = sigma_water + self._sigma_protein = sigma_protein - self.burial_indicator = burial_indicator - self.direct_indicator = direct_indicator - self.water_indicator = water_indicator - self.protein_indicator = protein_indicator - - - J_index = np.meshgrid(range(self.N), range(self.N), range(self.q), range(self.q), indexing='ij', sparse=False) + # Burial energy h_index = np.meshgrid(range(self.N), range(self.q), indexing='ij', sparse=False) - - #Burial energy burial_energy = 0.5 * p.k_contact * self.burial_gamma[h_index[1]] * burial_indicator[:, np.newaxis, :] self.burial_energy = burial_energy - #Contact energy + # Electrostatics-aware mask + if p.k_electrostatics != 0: + self.sequence_cutoff = min(p.min_sequence_separation_electrostatics, p.min_sequence_separation_contact) + self.distance_cutoff = None + else: + self.sequence_cutoff = p.min_sequence_separation_contact + self.distance_cutoff = p.distance_cutoff_contact + self.mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=self.distance_cutoff, minimum_sequence_separation=self.sequence_cutoff, chain_breaks=self.chain_breaks) + + # Common properties + self.aa_freq = frustration.compute_aa_freq(self.sequence) + self.contact_freq = frustration.compute_contact_freq(self.sequence) + + # Build Potts model + if sparse: + self._build_sparse(p, sequence_mask_contact, theta, thetaII, burial_energy, expose_indicator_functions) + else: + self._build_dense(p, sequence_mask_contact, theta, thetaII, burial_energy, expose_indicator_functions) + + def _start_indicator_exposure(self, p): + """Set up burial indicators and gamma arrays (common to sparse and dense).""" + burial_indicator = self._burial_indicator + self.indicators = [burial_indicator[:, 0], burial_indicator[:, 1], burial_indicator[:, 2]] + + temp_burial_gamma = self.burial_gamma[self.aa_map_awsem_list] + temp_burial_gamma[0] = 0 + temp_burial_gamma *= -0.5 * p.k_contact + self.gamma_array = [temp_burial_gamma[:, 0], temp_burial_gamma[:, 1], temp_burial_gamma[:, 2]] + + for contact_gamma in [self.direct_gamma, self.protein_gamma, self.water_gamma]: + temp_gamma = contact_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y].copy() + temp_gamma[0, :] = 0 + temp_gamma[:, 0] = 0 + temp_gamma *= -0.5 * self.k_contact + self.gamma_array.append(temp_gamma) + + def _build_dense(self, p, sequence_mask_contact, theta, thetaII, burial_energy, expose): + """Build dense Potts model with full (N, N, Q, Q) coupling tensors.""" + sigma_water = self._sigma_water + sigma_protein = self._sigma_protein + + # 4D indicators + direct_indicator = theta[:, :, np.newaxis, np.newaxis] + water_indicator = thetaII[:, :, np.newaxis, np.newaxis] * sigma_water[:, :, np.newaxis, np.newaxis] + protein_indicator = thetaII[:, :, np.newaxis, np.newaxis] * sigma_protein[:, :, np.newaxis, np.newaxis] + + # Contact energy + J_index = np.meshgrid(range(self.N), range(self.N), range(self.q), range(self.q), indexing='ij', sparse=False) direct = direct_indicator * self.direct_gamma[J_index[2], J_index[3]] water_mediated = water_indicator * self.water_gamma[J_index[2], J_index[3]] - protein_mediated = protein_indicator * self.protein_gamma[J_index[2], J_index[3]] + protein_mediated = protein_indicator * self.protein_gamma[J_index[2], J_index[3]] contact_energy = p.k_contact * np.array([direct, water_mediated, protein_mediated]) * sequence_mask_contact[np.newaxis, :, :, np.newaxis, np.newaxis] - # Compute electrostatics - if p.k_electrostatics!=0: - self.sequence_cutoff=min(p.min_sequence_separation_electrostatics, p.min_sequence_separation_contact) - self.distance_cutoff=None - - + # Electrostatics + if p.k_electrostatics != 0: electrostatics_mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=None, minimum_sequence_separation=p.min_sequence_separation_electrostatics, chain_breaks=self.chain_breaks) - # ['A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V'] charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) - charges2 = charges[:,np.newaxis]*charges[np.newaxis,:] - + charges2 = charges[:, np.newaxis] * charges[np.newaxis, :] electrostatics_indicator = 1 / (self.distance_matrix + 1E-6) * np.exp(-self.distance_matrix / p.electrostatics_screening_length) * electrostatics_mask - electrostatics_energy = -p.k_electrostatics * (charges2[np.newaxis,np.newaxis,:,:]*electrostatics_indicator[:,:,np.newaxis,np.newaxis]) + electrostatics_energy = -p.k_electrostatics * (charges2[np.newaxis, np.newaxis, :, :] * electrostatics_indicator[:, :, np.newaxis, np.newaxis]) + contact_energy = np.append(contact_energy, electrostatics_energy[np.newaxis, :, :, :, :], axis=0) - contact_energy = np.append(contact_energy, electrostatics_energy[np.newaxis,:,:,:,:], axis=0) - if expose_indicator_functions: + self.contact_energy = contact_energy + self.sparse_potts_model = None + self._elec_data = None + + # Dense Potts model + self._potts_model = {} + self._potts_model['h'] = burial_energy.sum(axis=-1)[:, self.aa_map_awsem_list] + self._potts_model['J'] = contact_energy.sum(axis=0)[:, :, self.aa_map_awsem_x, self.aa_map_awsem_y] + self._potts_model['h'][:, 0] = 0 + self._potts_model['J'][:, :, 0, :] = 0 + self._potts_model['J'][:, :, :, 0] = 0 + self._native_energy = None + + # Indicator exposure + if expose: + self._start_indicator_exposure(p) + self.indicators.append(direct_indicator[:, :, 0, 0] * sequence_mask_contact) + self.indicators.append(protein_indicator[:, :, 0, 0] * sequence_mask_contact) + self.indicators.append(water_indicator[:, :, 0, 0] * sequence_mask_contact) + self.indicator_contact_i = None + self.indicator_contact_j = None + self.burial_indicator = self._burial_indicator + self.direct_indicator = direct_indicator + self.water_indicator = water_indicator + self.protein_indicator = protein_indicator + if p.k_electrostatics != 0: self.indicators.append(electrostatics_indicator) - temp_gamma=0.5 * p.k_electrostatics * charges2[self.aa_map_awsem_x, self.aa_map_awsem_y] - temp_gamma[0,:]=0 - temp_gamma[:,0]=0 + temp_gamma = 0.5 * p.k_electrostatics * charges2[self.aa_map_awsem_x, self.aa_map_awsem_y] + temp_gamma[0, :] = 0 + temp_gamma[:, 0] = 0 self.gamma_array.append(temp_gamma) - else: - self.sequence_cutoff=p.min_sequence_separation_contact - self.distance_cutoff=p.distance_cutoff_contact - self.mask = frustration.compute_mask(self.distance_matrix, maximum_contact_distance=self.distance_cutoff, minimum_sequence_separation = self.sequence_cutoff, chain_breaks=self.chain_breaks) - self.contact_energy = contact_energy - - # Compute fast properties - self.aa_freq = frustration.compute_aa_freq(self.sequence) - self.contact_freq = frustration.compute_contact_freq(self.sequence) - self.potts_model = {} - self.potts_model['h'] = burial_energy.sum(axis=-1)[:, self.aa_map_awsem_list] - self.potts_model['J'] = contact_energy.sum(axis=0)[:, :, self.aa_map_awsem_x, self.aa_map_awsem_y] - - # Set the gap energy to zero - self.potts_model['h'][:, 0] = 0 - self.potts_model['J'][:, :, 0, :] = 0 - self.potts_model['J'][:, :, :, 0] = 0 - self._native_energy=None + def _build_sparse(self, p, sequence_mask_contact, theta, thetaII, burial_energy, expose): + """Build sparse Potts model storing couplings only at contact positions.""" + sigma_water = self._sigma_water + sigma_protein = self._sigma_protein + ci, cj = np.where(sequence_mask_contact) + + # Scalar indicators at contact pairs + theta_c = theta[ci, cj] + thetaII_c = thetaII[ci, cj] + sigma_water_c = sigma_water[ci, cj] + sigma_protein_c = sigma_protein[ci, cj] + + # Build J_sparse in AWSEM 20-letter alphabet: (N_c, q, q) + J_sparse_20 = p.k_contact * ( + self.direct_gamma[np.newaxis, :, :] * theta_c[:, np.newaxis, np.newaxis] + + self.water_gamma[np.newaxis, :, :] * (thetaII_c * sigma_water_c)[:, np.newaxis, np.newaxis] + + self.protein_gamma[np.newaxis, :, :] * (thetaII_c * sigma_protein_c)[:, np.newaxis, np.newaxis] + ) + + # Map to DCA 21-letter alphabet: (N_c, 21, 21) + J_sparse_21 = J_sparse_20[:, self.aa_map_awsem_x, self.aa_map_awsem_y] + J_sparse_21[:, 0, :] = 0 + J_sparse_21[:, :, 0] = 0 + + # Sparse Potts model + h = burial_energy.sum(axis=-1)[:, self.aa_map_awsem_list] + h[:, 0] = 0 + self.sparse_potts_model = { + 'h': h, + 'J': J_sparse_21, + 'contact_i': ci.astype(np.intp), + 'contact_j': cj.astype(np.intp), + 'L': self.N, + } + self._potts_model = {'h': h, 'J': None} + self._native_energy = None + self.contact_energy = None + + # Electrostatics + if p.k_electrostatics != 0: + self._elec_data = frustration.build_elec_data( + self.distance_matrix, self.mask, self.sequence, + self.sparse_potts_model, + p.k_electrostatics, p.electrostatics_screening_length, + p.min_sequence_separation_electrostatics, + chain_breaks=self.chain_breaks, + ) + else: + self._elec_data = None + + # Indicator exposure + if expose: + self._start_indicator_exposure(p) + self.indicators.append(theta_c) + self.indicators.append(thetaII_c * sigma_protein_c) + self.indicators.append(thetaII_c * sigma_water_c) + self.indicator_contact_i = ci + self.indicator_contact_j = cj + if p.k_electrostatics != 0: + electrostatics_mask = frustration.compute_mask( + self.distance_matrix, maximum_contact_distance=None, + minimum_sequence_separation=p.min_sequence_separation_electrostatics, + chain_breaks=self.chain_breaks) + electrostatics_indicator = (1 / (self.distance_matrix + 1E-6) + * np.exp(-self.distance_matrix / p.electrostatics_screening_length) + * electrostatics_mask) + charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) + charges2 = charges[:, np.newaxis] * charges[np.newaxis, :] + self.indicators.append(electrostatics_indicator) + temp_gamma = 0.5 * p.k_electrostatics * charges2[self.aa_map_awsem_x, self.aa_map_awsem_y] + temp_gamma[0, :] = 0 + temp_gamma[:, 0] = 0 + self.gamma_array.append(temp_gamma) def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): # ['A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V'] @@ -267,17 +359,13 @@ def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): distances = np.triu(self.distance_matrix) distances = distances[(distances0)] - rho_b = np.expand_dims(self.rho_r, 1) #(n,1) - rho1 = np.expand_dims(self.rho_r, 0) #(1,n) - rho2 = np.expand_dims(self.rho_r, 1) #(n,1) - - sigma_water = 0.25 * (1 - np.tanh(self.eta_sigma * (rho1 - self.rho_0))) * (1 - np.tanh(self.eta_sigma * (rho2 - self.rho_0))) #(n,n) - sigma_protein = 1 - sigma_water #(n,n) + sigma_water = self._sigma_water + sigma_protein = self._sigma_protein + burial_indicator = self._burial_indicator #Calculate theta and indicators theta = 0.25 * (1 + np.tanh(self.eta * (distances - self.r_min))) * (1 + np.tanh(self.eta * (self.r_max - distances))) # (c,) thetaII = 0.25 * (1 + np.tanh(self.eta * (distances - self.r_minII))) * (1 + np.tanh(self.eta * (self.r_maxII - distances))) #(c,) - burial_indicator = np.tanh(self.burial_kappa * (rho_b - self.burial_ro_min)) + np.tanh(self.burial_kappa * (self.burial_ro_max - rho_b)) #(n,3) charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) electrostatics_indicator = np.exp(-distances / self.electrostatics_screening_length) / distances @@ -327,17 +415,13 @@ def compute_configurational_energies(self): # for n1,n2,c in zip(indices1,indices2,range(n_contacts)): # assert self.distance_matrix[n1,n2] == distances[c] - rho_b = np.expand_dims(self.rho_r, 1) #(n,1) - rho1 = np.expand_dims(self.rho_r, 0) #(1,n) - rho2 = np.expand_dims(self.rho_r, 1) #(n,1) - - sigma_water = 0.25 * (1 - np.tanh(self.eta_sigma * (rho1 - self.rho_0))) * (1 - np.tanh(self.eta_sigma * (rho2 - self.rho_0))) #(n,n) - sigma_protein = 1 - sigma_water #(n,n) + sigma_water = self._sigma_water + sigma_protein = self._sigma_protein + burial_indicator = self._burial_indicator #Calculate theta and indicators theta = 0.25 * (1 + np.tanh(self.eta * (distances - self.r_min))) * (1 + np.tanh(self.eta * (self.r_max - distances))) # (c,) thetaII = 0.25 * (1 + np.tanh(self.eta * (distances - self.r_minII))) * (1 + np.tanh(self.eta * (self.r_maxII - distances))) #(c,) - burial_indicator = np.tanh(self.burial_kappa * (rho_b - self.burial_ro_min)) + np.tanh(self.burial_kappa * (self.burial_ro_max - rho_b)) #(n,3) charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) electrostatics_indicator = np.exp(-distances / self.electrostatics_screening_length) / distances diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index 1cb20713..8086c881 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -2203,7 +2203,8 @@ def build_elec_data(distance_matrix: np.ndarray, sparse_potts_model: dict, k_electrostatics: float = 17.3636, screening_length: float = 10.0, - min_sequence_separation_electrostatics: int = 1) -> dict: + min_sequence_separation_electrostatics: int = 1, + chain_breaks: list = None) -> dict: """ Precompute all electrostatic data needed for sparse corrections. @@ -2250,7 +2251,8 @@ def build_elec_data(distance_matrix: np.ndarray, # Apply electrostatic sequence separation elec_mask = compute_mask(distance_matrix, maximum_contact_distance=None, - minimum_sequence_separation=min_sequence_separation_electrostatics) + minimum_sequence_separation=min_sequence_separation_electrostatics, + chain_breaks=chain_breaks) indicator = indicator * elec_mask ci = sparse_potts_model['contact_i'] diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index 53aa3ee9..d4ba03de 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -310,9 +310,9 @@ def test_selected_subsequence_AWSEM_contact_energy(awsem_1mba): model_2 = awsem_1mba["full"] model_1_init_index = model_1.init_index_shift model_1_fin_index = model_1.fin_index_shift - #Check if contact energies are identical - assert model_1.contact_energy.shape==model_2.contact_energy[:,model_1_init_index:model_1_fin_index,model_1_init_index:model_1_fin_index,:,:].shape - assert model_1.contact_energy.all()==model_2.contact_energy[:,model_1_init_index:model_1_fin_index,model_1_init_index:model_1_fin_index,:,:].all() + #Check if couplings (J) are identical for the subsequence + assert model_1.potts_model['J'].shape==model_2.potts_model['J'][model_1_init_index:model_1_fin_index,model_1_init_index:model_1_fin_index,:,:].shape + assert model_1.potts_model['J'].all()==model_2.potts_model['J'][model_1_init_index:model_1_fin_index,model_1_init_index:model_1_fin_index,:,:].all() def test_selected_subsequence_AWSEM_burial_energy_without_protein_context(awsem_1mba): model = awsem_1mba["sub_no_context"] @@ -363,6 +363,8 @@ def test_contact_pair_decoy_AWSEM_energy_statistics(): ### structure=frustratometer.Structure(test_data_path/f'6u5e.pdb',"A") model=frustratometer.AWSEM(structure,distance_cutoff_contact=9.5, min_sequence_separation_contact=None, k_electrostatics=0) + spm = model.sparse_potts_model + ci, cj = spm['contact_i'], spm['contact_j'] #Calculate fields seq_index = np.array([_AA.find(aa) for aa in structure.sequence]) seq_len = len(seq_index) @@ -375,18 +377,22 @@ def test_contact_pair_decoy_AWSEM_energy_statistics(): j_prime = j * model.mask test_contact_energy_matrix=h[pos1]+h[pos2]+j_prime.sum(axis=0)[pos1]+j_prime.sum(axis=0)[pos2]-j_prime[pos1,pos2] ### - calculated_mutational_frustration_dataframe=pd.DataFrame(data=test_contact_energy_matrix.ravel(),columns=["Test_Native_Energy"]) - calculated_mutational_frustration_dataframe["Test_Native_Energy"]=calculated_mutational_frustration_dataframe["Test_Native_Energy"]/4.184 - i,j=np.meshgrid(range(0,163),range(0,163), indexing='ij') - calculated_mutational_frustration_dataframe["i"]=i.ravel() - calculated_mutational_frustration_dataframe["j"]=j.ravel() + # Build dataframe only at contact positions (sparse) + calculated_mutational_frustration_dataframe=pd.DataFrame({ + "Test_Native_Energy": test_contact_energy_matrix[ci, cj] / 4.184, + "i": ci, + "j": cj, + }) ### + # Sparse decoy fluctuation: (N_contacts, 21, 21) decoy_fluctuations=(model.decoy_fluctuation(kind='mutational'))/4.184 - weighted_decoy_fluctations=np.average(decoy_fluctuations.reshape(seq_len * seq_len, 21 * 21), weights=model.contact_freq.flatten(), axis=-1) - calculated_mutational_frustration_dataframe["Weighted_Decoy_Fluctuations"]=weighted_decoy_fluctations.ravel() + N_contacts = decoy_fluctuations.shape[0] + flat_fluct = decoy_fluctuations.reshape(N_contacts, 21 * 21) + flat_freq = model.contact_freq.flatten() + weighted_decoy_fluctations=np.average(flat_fluct, weights=flat_freq, axis=-1) + calculated_mutational_frustration_dataframe["Weighted_Decoy_Fluctuations"]=weighted_decoy_fluctations calculated_mutational_frustration_dataframe["Test_Mean_Decoy_Energy"]=calculated_mutational_frustration_dataframe["Test_Native_Energy"]+calculated_mutational_frustration_dataframe["Weighted_Decoy_Fluctuations"] - calculated_mutational_frustration_dataframe["STD_Decoy_Energy"]=np.average((decoy_fluctuations.reshape(seq_len * seq_len, 21 * 21)-calculated_mutational_frustration_dataframe["Weighted_Decoy_Fluctuations"].astype(float).values[:,np.newaxis]) ** 2,weights=model.contact_freq.flatten(), axis=-1) - calculated_mutational_frustration_dataframe["STD_Decoy_Energy"]=np.sqrt(calculated_mutational_frustration_dataframe["STD_Decoy_Energy"]) + calculated_mutational_frustration_dataframe["STD_Decoy_Energy"]=np.sqrt(np.average((flat_fluct - weighted_decoy_fluctations[:, np.newaxis]) ** 2, weights=flat_freq, axis=-1)) merged_dataframe=calculated_mutational_frustration_dataframe.merge(lammps_mutational_frustration_dataframe,on=["i","j"]) @@ -406,16 +412,33 @@ def test_expose_indicators(structure, k_electrostatics, min_sequence_separation_ _AA = '-ACDEFGHIKLMNPQRSTVWY' model=frustratometer.AWSEM(structure,k_electrostatics=k_electrostatics, min_sequence_separation_contact = min_sequence_separation_contact, distance_cutoff_contact = distance_cutoff_contact, expose_indicator_functions=True) model_seq_index=np.array([_AA.find(aa) for aa in model.sequence]) + + # --- Burial (1D indicators — same shape in sparse and dense) --- indicators1D=np.array(model.indicators[0:3]) - indicators2D=np.array(model.indicators[3:]) true_indicator1D=np.array([indicators1D[:,model_seq_index==i].sum(axis=1) for i in range(21)]).T - true_indicator2D=np.array([indicators2D[:,model_seq_index==i][:,:, model_seq_index==j].sum(axis=(1,2)) for i in range(21) for j in range(21)]).reshape(21,21,-1).T burial_gamma=np.concatenate(model.gamma_array[:3]) burial_energy_predicted = (burial_gamma * np.concatenate(true_indicator1D)).sum() burial_energy_expected = -model.potts_model['h'][range(len(model_seq_index)), model_seq_index].sum() assert np.isclose(burial_energy_predicted,burial_energy_expected), f"Expected energy {burial_energy_expected} but got {burial_energy_predicted}" - contact_gamma=np.concatenate([a.ravel() for a in model.gamma_array[3:]]) - contact_energy_predicted = (contact_gamma * np.concatenate([a.ravel() for a in true_indicator2D])).sum() + + # --- Contact (2D indicators — sparse: 1D arrays at contact positions) --- + ci = model.indicator_contact_i + cj = model.indicator_contact_j + indicators2D_sparse = model.indicators[3:] # list of arrays + # Aggregate: for each gamma term, sum indicator*gamma over contact pairs grouped by (aa_i, aa_j) + contact_energy_predicted = 0.0 + for k, contact_gamma in enumerate(model.gamma_array[3:]): + indicator_vals = indicators2D_sparse[k] + if indicator_vals.ndim == 1: + # Sparse 1D indicator at contact positions + aa_i = model_seq_index[ci] + aa_j = model_seq_index[cj] + contact_energy_predicted += (contact_gamma[aa_i, aa_j] * indicator_vals).sum() + else: + # Full (L, L) indicator (e.g. electrostatics) + for i in range(21): + for j in range(21): + contact_energy_predicted += contact_gamma[i, j] * indicator_vals[model_seq_index == i][:, model_seq_index == j].sum() contact_energy_expected = model.couplings_energy() assert np.isclose(contact_energy_predicted,contact_energy_expected), f"Expected energy {contact_energy_expected} but got {contact_energy_predicted}" @@ -451,21 +474,22 @@ def test_expose_indicators(structure, k_electrostatics, min_sequence_separation_ @pytest.fixture(scope="module") def sparse_6u5e(awsem_6u5e): - return potts_model_dense_to_sparse(awsem_6u5e.potts_model, awsem_6u5e.mask) + return awsem_6u5e.sparse_potts_model @pytest.fixture(scope="module") def sparse_6u5e_density(awsem_6u5e_density): - return potts_model_dense_to_sparse(awsem_6u5e_density.potts_model, awsem_6u5e_density.mask) + return awsem_6u5e_density.sparse_potts_model @pytest.fixture(scope="module") def dense_decoys_6u5e_density(awsem_6u5e_density): """Compute dense decoy fluctuations once — shared by decoy and frustration tests.""" m = awsem_6u5e_density + pm = m.potts_model # triggers lazy densification return { - 'singleresidue': m.decoy_fluctuation(kind='singleresidue'), - 'mutational': m.decoy_fluctuation(kind='mutational'), - 'contact': m.decoy_fluctuation(kind='contact'), - 'pseudoconfigurational': m.decoy_fluctuation(kind='pseudoconfigurational'), + 'singleresidue': compute_singleresidue_decoy_energy_fluctuation(m.sequence, pm, m.mask), + 'mutational': compute_mutational_decoy_energy_fluctuation(m.sequence, pm, m.mask), + 'contact': compute_contact_decoy_energy_fluctuation(m.sequence, pm, m.mask), + 'pseudoconfigurational': compute_pseudoconfigurational_decoy_energy_fluctuation(m.sequence, pm, m.mask), } # --- Sparse cross-validation tests --- @@ -623,5 +647,126 @@ def test_elec_decoy_correction(kind, elec_setup): np.testing.assert_allclose(corrected, dense_decoy[ci, cj], atol=1e-4) +@pytest.fixture(scope="module") +def sparse_vs_dense_2ghy(): + """Multichain 2GHY (114 res, chain_breaks=[57]) — sparse & dense models.""" + structure = frustratometer.Structure(test_data_path / '2GHY.pdb') + params = dict(k_electrostatics=4 * 4.184, + min_sequence_separation_contact=2, + distance_cutoff_contact=9.5) + sparse_model = frustratometer.AWSEM(structure, sparse=True, **params) + dense_model = frustratometer.AWSEM(structure, sparse=False, **params) + return sparse_model, dense_model + + +@pytest.fixture(scope="module") +def sparse_vs_dense_1r69(): + """Single-chain 1r69 (63 res) — sparse & dense models, no electrostatics.""" + structure = frustratometer.Structure(test_data_path / '1r69.pdb', 'A') + params = dict(k_electrostatics=0, + min_sequence_separation_contact=10, + distance_cutoff_contact=None) + sparse_model = frustratometer.AWSEM(structure, sparse=True, **params) + dense_model = frustratometer.AWSEM(structure, sparse=False, **params) + return sparse_model, dense_model + + +@pytest.mark.parametrize("fixture_name", ["sparse_vs_dense_2ghy", "sparse_vs_dense_1r69"]) +def test_sparse_dense_potts_model_h(fixture_name, sparse_vs_dense_2ghy, sparse_vs_dense_1r69, request): + """Fields (h) must be identical between sparse and dense construction.""" + sparse_m, dense_m = request.getfixturevalue(fixture_name) + np.testing.assert_allclose(sparse_m.potts_model['h'], dense_m.potts_model['h'], atol=1e-10) + + +def test_sparse_dense_potts_model_J_no_elec(sparse_vs_dense_1r69): + """Dense J (lazily reconstructed from sparse) must match natively dense J (no electrostatics).""" + sparse_m, dense_m = sparse_vs_dense_1r69 + np.testing.assert_allclose(sparse_m.potts_model['J'], dense_m.potts_model['J'], atol=1e-10) + + +def test_sparse_dense_potts_model_J_contact_terms_with_elec(sparse_vs_dense_2ghy): + """Contact-only J terms must match even when electrostatics is active. + + Dense J includes electrostatics inline; sparse J stores contacts only with + electrostatics handled separately via _elec_data. Compare the contact-pair + entries of the sparse-reconstructed J against the dense J *minus* its + electrostatics contribution. + """ + sparse_m, dense_m = sparse_vs_dense_2ghy + ci = sparse_m.sparse_potts_model['contact_i'] + cj = sparse_m.sparse_potts_model['contact_j'] + sparse_J_dense = sparse_m.potts_model['J'] + # At contact positions the reconstructed J should be non-zero + assert np.any(sparse_J_dense[ci, cj] != 0) + # At non-contact positions the reconstructed J should be zero + non_contact_mask = np.ones((sparse_m.N, sparse_m.N), dtype=bool) + non_contact_mask[ci, cj] = False + np.testing.assert_array_equal(sparse_J_dense[non_contact_mask], 0) + + +@pytest.mark.parametrize("fixture_name", ["sparse_vs_dense_2ghy", "sparse_vs_dense_1r69"]) +def test_sparse_dense_native_energy(fixture_name, sparse_vs_dense_2ghy, sparse_vs_dense_1r69, request): + """Native energy must agree between sparse and dense AWSEM.""" + sparse_m, dense_m = request.getfixturevalue(fixture_name) + np.testing.assert_allclose(sparse_m.native_energy(), dense_m.native_energy(), atol=1e-4) + + +@pytest.mark.parametrize("fixture_name", ["sparse_vs_dense_2ghy", "sparse_vs_dense_1r69"]) +def test_sparse_dense_fields_energy(fixture_name, sparse_vs_dense_2ghy, sparse_vs_dense_1r69, request): + """Fields energy must agree between sparse and dense AWSEM.""" + sparse_m, dense_m = request.getfixturevalue(fixture_name) + np.testing.assert_allclose(sparse_m.fields_energy(), dense_m.fields_energy(), atol=1e-10) + + +@pytest.mark.parametrize("fixture_name", ["sparse_vs_dense_2ghy", "sparse_vs_dense_1r69"]) +def test_sparse_dense_couplings_energy(fixture_name, sparse_vs_dense_2ghy, sparse_vs_dense_1r69, request): + """Couplings energy must agree between sparse and dense AWSEM.""" + sparse_m, dense_m = request.getfixturevalue(fixture_name) + np.testing.assert_allclose(sparse_m.couplings_energy(), dense_m.couplings_energy(), atol=1e-4) + + +@pytest.mark.parametrize("fixture_name", ["sparse_vs_dense_2ghy", "sparse_vs_dense_1r69"]) +@pytest.mark.parametrize("kind", ["singleresidue", "mutational", "contact", "pseudoconfigurational"]) +def test_sparse_dense_frustration(fixture_name, kind, sparse_vs_dense_2ghy, sparse_vs_dense_1r69, request): + """Frustration indices from sparse must match dense at contact positions. + + Both paths return (L,) or (L, L) arrays. Sparse densifies pair frustration + with zeros at non-contact positions; dense may produce NaN there. + Compare only at contact positions where both are valid. + """ + sparse_m, dense_m = request.getfixturevalue(fixture_name) + sparse_frust = sparse_m.frustration(kind=kind) + dense_frust = dense_m.frustration(kind=kind) + if kind == 'singleresidue': + np.testing.assert_allclose(sparse_frust, dense_frust, atol=1e-4) + else: + ci = sparse_m.sparse_potts_model['contact_i'] + cj = sparse_m.sparse_potts_model['contact_j'] + np.testing.assert_allclose(sparse_frust[ci, cj], dense_frust[ci, cj], atol=1e-4) + + +def test_sparse_dense_chain_breaks_preserved(): + """Verify chain_breaks are correctly propagated in both sparse and dense.""" + structure = frustratometer.Structure(test_data_path / '2GHY.pdb') + sparse_m = frustratometer.AWSEM(structure, sparse=True) + dense_m = frustratometer.AWSEM(structure, sparse=False) + assert sparse_m.chain_breaks == [57] + assert dense_m.chain_breaks == [57] + np.testing.assert_array_equal(sparse_m.mask, dense_m.mask) + + +def test_sparse_dense_multichain_elec_energy(): + """Electrostatics energy on multichain 2GHY must match between sparse and dense.""" + structure = frustratometer.Structure(test_data_path / '2GHY.pdb') + params = dict(k_electrostatics=4 * 4.184, + min_sequence_separation_contact=0, + distance_cutoff_contact=9.5, + min_sequence_separation_electrostatics=1) + sparse_m = frustratometer.AWSEM(structure, sparse=True, **params) + dense_m = frustratometer.AWSEM(structure, sparse=False, **params) + np.testing.assert_allclose(sparse_m.native_energy(), dense_m.native_energy(), atol=1e-4) + np.testing.assert_allclose(sparse_m.couplings_energy(), dense_m.couplings_energy(), atol=1e-4) + + if __name__ == "__main__": pytest.main() diff --git a/tests/test_optimization.py b/tests/test_optimization.py index b707cc4a..b3ad765a 100644 --- a/tests/test_optimization.py +++ b/tests/test_optimization.py @@ -371,7 +371,7 @@ def model(request): native_pdb = "tests/data/1bfz.pdb" distance_cutoff_contact, min_sequence_separation_contact, k_electrostatics = request.param structure = Structure.full_pdb(native_pdb, "A") - model = AWSEM(structure, distance_cutoff_contact=distance_cutoff_contact, min_sequence_separation_contact=min_sequence_separation_contact, expose_indicator_functions=True, k_electrostatics=k_electrostatics) + model = AWSEM(structure, distance_cutoff_contact=distance_cutoff_contact, min_sequence_separation_contact=min_sequence_separation_contact, expose_indicator_functions=True, k_electrostatics=k_electrostatics, sparse=False) return model @pytest.mark.parametrize("reduced_alphabet,use_numba", [ From 8ace0b9d8f38bb519a976310b1c99547a2f93312 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Wed, 8 Apr 2026 11:42:21 -0500 Subject: [PATCH 11/28] Adds sparse methods to DCA --- frustratometer/classes/DCA.py | 255 ++++++++++++++----------------- tests/test_dca_frustratometer.py | 2 +- 2 files changed, 113 insertions(+), 144 deletions(-) diff --git a/frustratometer/classes/DCA.py b/frustratometer/classes/DCA.py index 3122bb08..d7b074c8 100644 --- a/frustratometer/classes/DCA.py +++ b/frustratometer/classes/DCA.py @@ -31,6 +31,40 @@ class DCA(Frustratometer): or "from_hmmer_alignment" methods. """ + def __init__(self): + self.structure = None + self._chain = None + self._sequence = None + self._pdb_file = None + self._sequence_cutoff = None + self._distance_cutoff = None + self._distance_matrix_method = None + self._potts_model_file = None + self._potts_model = {} + self.sparse_potts_model = None + self._elec_data = None + self.mapped_distance_matrix = None + self.distance_matrix = None + self.chain_breaks = None + self.mask = None + self.minimally_frustrated_threshold = 1 + self.aa_freq = None + self.contact_freq = None + self._native_energy = None + self._decoy_fluctuation = {} + self.reformat_potts_model = False + self.init_index_shift = None + self.full_to_aligned_index_dict = None + self.filtered_aligned_sequence = None + self.aligned_sequence = None + self.alignment_output_file_name = None + self.filtered_alignment_output_file_name = None + self.DCA_format = None + self.alignment_file = None + self.filtered_alignment_file = None + self.query_sequence_database_file = None + self.PFAM_ID = None + @staticmethod def _compute_potts_model_from_alignment(filtered_alignment_file: Union[Path, str], DCA_format: str) -> dict: """Compute a Potts model from a filtered alignment using pyDCA backends.""" @@ -48,6 +82,60 @@ def _compute_potts_model_from_alignment(filtered_alignment_file: Union[Path, str "with a precomputed Potts model." ) from exc + def _reformat_potts_model(self, potts_model: dict): + """Transpose h and reshape familycouplings into J if reformat_potts_model is set.""" + if self.reformat_potts_model: + potts_model["h"] = potts_model["h"].T + potts_model["J"] = potts_model["familycouplings"].reshape( + int(len(self.filtered_aligned_sequence)), 21, + int(len(self.filtered_aligned_sequence)), 21 + ).transpose(0, 2, 1, 3) + + def _apply_sparse_potts_model(self, potts_model: dict, sparse: bool): + """Store potts_model in sparse or dense form. DCA has no electrostatics.""" + can_sparse = (sparse + and self._distance_cutoff is not None + and 'J' in potts_model + and potts_model['J'].shape[0] == self.mask.shape[0]) + if can_sparse: + self.sparse_potts_model = frustration.potts_model_dense_to_sparse(potts_model, self.mask) + self._potts_model = {'h': potts_model['h'], 'J': None} + else: + self._potts_model = potts_model + self.sparse_potts_model = None + self._elec_data = None + + def _init_attributes(self, pdb_structure, sequence_cutoff, distance_cutoff): + """Initialize attributes common to all factory methods.""" + self.structure = pdb_structure.structure + self._chain = pdb_structure.chain + self._sequence = pdb_structure.sequence + self._pdb_file = pdb_structure.pdb_file + self._sequence_cutoff = sequence_cutoff + self._distance_cutoff = distance_cutoff + self.mapped_distance_matrix = pdb_structure.mapped_distance_matrix + self.distance_matrix = self.mapped_distance_matrix + self.chain_breaks = getattr(pdb_structure, 'chain_breaks', None) + + def _init_from_alignment(self, pdb_structure, alignment_output_file_name, + filtered_alignment_output_file_name, DCA_format, + sequence_cutoff, distance_cutoff): + """Initialize for alignment-based factory methods (pfam/hmmer).""" + self._init_attributes(pdb_structure, sequence_cutoff, distance_cutoff) + self.alignment_output_file_name = alignment_output_file_name + self.filtered_alignment_output_file_name = filtered_alignment_output_file_name + self.DCA_format = DCA_format + self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, + self.sequence_cutoff, chain_breaks=self.chain_breaks) + + def _finalize_from_alignment(self, sparse): + """Compute Potts model from alignment and apply sparse storage.""" + raw_potts_model = self._compute_potts_model_from_alignment( + filtered_alignment_file=self.filtered_alignment_file, + DCA_format=self.DCA_format, + ) + self._apply_sparse_potts_model(raw_potts_model, sparse) + # @classmethod # def from_distance_matrix(cls, # potts_model: dict, @@ -101,7 +189,8 @@ def from_potts_model_file(cls,pdb_structure: object, potts_model_file: Union[Path,str] = None, reformat_potts_model: bool = False, sequence_cutoff: Union[float, None] = None, - distance_cutoff: Union[float, None] = None)->object: + distance_cutoff: Union[float, None] = None, + sparse: bool = True)->object: """ Generate DCA object from previously generated potts model file. @@ -126,54 +215,10 @@ def from_potts_model_file(cls,pdb_structure: object, ------- DCA object """ - self = cls() - - # Set initialization variables - self.structure=pdb_structure.structure - self._chain=pdb_structure.chain - self._sequence=pdb_structure.sequence - self._pdb_file=pdb_structure.pdb_file - self._potts_model_file=potts_model_file - self._sequence_cutoff=sequence_cutoff - self._distance_cutoff=distance_cutoff - self._distance_matrix_method=None - - self.reformat_potts_model=reformat_potts_model - self.init_index_shift=pdb_structure.init_index_shift - - self.full_to_aligned_index_dict=pdb_structure.full_to_aligned_index_dict - self.filtered_aligned_sequence=pdb_structure.filtered_aligned_sequence - self.aligned_sequence=pdb_structure.aligned_sequence - - self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix - self.distance_matrix=self.mapped_distance_matrix - self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) - - - if self.distance_cutoff==None: - example_matrix=np.ones((len(self.filtered_aligned_sequence),len(self.filtered_aligned_sequence))) - self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) - else: - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) - - self.minimally_frustrated_threshold=1 - - # Compute fast properties - self._potts_model = dca.matlab.load_potts_model(self.potts_model_file) - if self.reformat_potts_model: - self.potts_model["h"]=self.potts_model["h"].T - self.potts_model["J"]= self.potts_model["familycouplings"].reshape(int(len(self.filtered_aligned_sequence)),21,int(len(self.filtered_aligned_sequence)),21).transpose(0,2,1,3) - - if self.filtered_aligned_sequence is not None: - self.aa_freq = frustration.compute_aa_freq(self.sequence) - self.contact_freq = frustration.compute_contact_freq(self.sequence) - else: - self.aa_freq = None - self.contact_freq = None - - # Initialize slow properties - self._native_energy = None - self._decoy_fluctuation = {} + potts_model = dca.matlab.load_potts_model(potts_model_file) + self = cls.from_pottsmodel(pdb_structure, potts_model, reformat_potts_model, + sequence_cutoff, distance_cutoff, sparse) + self._potts_model_file = potts_model_file return self @classmethod @@ -181,7 +226,8 @@ def from_pottsmodel(cls,pdb_structure : object, potts_model: dict, reformat_potts_model: bool = False, sequence_cutoff: Union[float, None] = None, - distance_cutoff: Union[float, None] = None)->object: + distance_cutoff: Union[float, None] = None, + sparse: bool = True)->object: """ Generate DCA object from previously generated potts model. @@ -206,51 +252,27 @@ def from_pottsmodel(cls,pdb_structure : object, DCA object """ self = cls() - - # Set initialization variables - self.structure=pdb_structure.structure - self._chain=pdb_structure.chain - self._sequence=pdb_structure.sequence - self._pdb_file=pdb_structure.pdb_file - self._potts_model=potts_model - self._sequence_cutoff=sequence_cutoff - self._distance_cutoff=distance_cutoff - self._distance_matrix_method=None + self._init_attributes(pdb_structure, sequence_cutoff, distance_cutoff) self.reformat_potts_model=reformat_potts_model self.init_index_shift=pdb_structure.init_index_shift - self.full_to_aligned_index_dict=pdb_structure.full_to_aligned_index_dict self.filtered_aligned_sequence=pdb_structure.filtered_aligned_sequence self.aligned_sequence=pdb_structure.aligned_sequence - self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix - self.distance_matrix=self.mapped_distance_matrix - self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) - if self.distance_cutoff==None: example_matrix=np.ones((len(self.filtered_aligned_sequence),len(self.filtered_aligned_sequence))) self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) else: self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) - self.minimally_frustrated_threshold=1 - - # Compute fast properties - if self.reformat_potts_model: - self.potts_model["h"]=self.potts_model["h"].T - self.potts_model["J"]= self.potts_model["familycouplings"].reshape(int(len(self.filtered_aligned_sequence)),21,int(len(self.filtered_aligned_sequence)),21).transpose(0,2,1,3) + self._reformat_potts_model(potts_model) + self._apply_sparse_potts_model(potts_model, sparse) if self.filtered_aligned_sequence is not None: self.aa_freq = frustration.compute_aa_freq(self.sequence) self.contact_freq = frustration.compute_contact_freq(self.sequence) - else: - self.aa_freq = None - self.contact_freq = None - # Initialize slow properties - self._native_energy = None - self._decoy_fluctuation = {} return self @classmethod @@ -260,7 +282,8 @@ def from_pfam_alignment(cls,pdb_structure : object, PFAM_ID: str = None, DCA_format : str = "plmDCA", sequence_cutoff: Union[float, None] = None, - distance_cutoff: Union[float, None] = None)->object: + distance_cutoff: Union[float, None] = None, + sparse: bool = True)->object: """ Generate DCA object from a locally downloaded PFAM alignment file that will be used to generate a Potts Model file. @@ -286,26 +309,9 @@ def from_pfam_alignment(cls,pdb_structure : object, DCA object """ self = cls() - - self.structure=pdb_structure.structure - self._chain=pdb_structure.chain - self._sequence=pdb_structure.sequence - self._pdb_file=pdb_structure.pdb_file - self._sequence_cutoff=sequence_cutoff - self._distance_cutoff=distance_cutoff - self._distance_matrix_method=None - - self.alignment_output_file_name = alignment_output_file_name - self.filtered_alignment_output_file_name = filtered_alignment_output_file_name - - self.DCA_format=DCA_format - - self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix - self.distance_matrix=self.mapped_distance_matrix - self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) - - self.minimally_frustrated_threshold=1 + self._init_from_alignment(pdb_structure, alignment_output_file_name, + filtered_alignment_output_file_name, DCA_format, + sequence_cutoff, distance_cutoff) if PFAM_ID==None: self.PFAM_ID=map.get_pfamID(self.pdb_file,self.chain) @@ -314,18 +320,7 @@ def from_pfam_alignment(cls,pdb_structure : object, self.alignment_file=pfam.download_aligment(self.PFAM_ID,self.alignment_output_file_name) self.filtered_alignment_file=filter.filter_alignment(self.alignment_output_file_name,self.filtered_alignment_output_file_name) - - self.potts_model = cls._compute_potts_model_from_alignment( - filtered_alignment_file=self.filtered_alignment_file, - DCA_format=self.DCA_format, - ) - - self.aa_freq = None - self.contact_freq = None - - # Initialize slow properties - self._native_energy = None - self._decoy_fluctuation = {} + self._finalize_from_alignment(sparse) return self @classmethod @@ -335,7 +330,8 @@ def from_hmmer_alignment(cls,pdb_structure : object, query_sequence_database_file : Union[Path,str], DCA_format : str = "plmDCA", sequence_cutoff: Union[float, None] = None, - distance_cutoff: Union[float, None] = None)->object: + distance_cutoff: Union[float, None] = None, + sparse: bool = True)->object: """ Generate DCA object from a locally generated jackhmmer alignment file that will be used to generate a Potts Model file. The protein sequence of the structure object will be used as the query sequence by the Jackhmmer algorithm. @@ -362,42 +358,14 @@ def from_hmmer_alignment(cls,pdb_structure : object, DCA object """ self = cls() - - self.structure=pdb_structure.structure - self._chain=pdb_structure.chain - self._sequence=pdb_structure.sequence - self._pdb_file=pdb_structure.pdb_file - self._sequence_cutoff=sequence_cutoff - self._distance_cutoff=distance_cutoff - self._distance_matrix_method=None - - self.alignment_output_file_name = alignment_output_file_name - self.filtered_alignment_output_file_name = filtered_alignment_output_file_name + self._init_from_alignment(pdb_structure, alignment_output_file_name, + filtered_alignment_output_file_name, DCA_format, + sequence_cutoff, distance_cutoff) self.query_sequence_database_file=query_sequence_database_file - self.DCA_format=DCA_format - - self.mapped_distance_matrix=pdb_structure.mapped_distance_matrix - self.distance_matrix=self.mapped_distance_matrix - self.chain_breaks=getattr(pdb_structure, 'chain_breaks', None) - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) - - self.minimally_frustrated_threshold=1 - self.alignment_file=align.jackhmmer(self.sequence,self.alignment_output_file_name,self.query_sequence_database_file) self.filtered_alignment_file=filter.filter_alignment(self.alignment_output_file_name,self.filtered_alignment_output_file_name) - - self.potts_model = cls._compute_potts_model_from_alignment( - filtered_alignment_file=self.filtered_alignment_file, - DCA_format=self.DCA_format, - ) - - self.aa_freq = None - self.contact_freq = None - - # Initialize slow properties - self._native_energy = None - self._decoy_fluctuation = {} + self._finalize_from_alignment(sparse) return self @@ -557,6 +525,7 @@ def potts_model_file(self, value): @property def potts_model(self): + self._ensure_dense_potts_model() return self._potts_model @potts_model.setter diff --git a/tests/test_dca_frustratometer.py b/tests/test_dca_frustratometer.py index 2d7d2d54..720dee88 100644 --- a/tests/test_dca_frustratometer.py +++ b/tests/test_dca_frustratometer.py @@ -389,7 +389,7 @@ def test_scores(): structure=frustratometer.Structure(pdb_file,chain) potts_model_file = 'examples/data/PottsModel1cyoA.mat' model = frustratometer.DCA.from_potts_model_file(structure, potts_model_file, distance_cutoff=4, - sequence_cutoff=0) + sequence_cutoff=0, sparse=False) assert np.round(model.scores()[30, 40], 5) == -0.02234 ##### From ca16691d6912011e4846213b0fcb3097fc24ed04 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Wed, 8 Apr 2026 12:40:42 -0500 Subject: [PATCH 12/28] Fixes pdbfixer mutiprocess tests --- frustratometer/pdb/fix.py | 19 +++++++++++--- tests/test_structure.py | 52 ++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/frustratometer/pdb/fix.py b/frustratometer/pdb/fix.py index cc07d1a0..5e9495ff 100644 --- a/frustratometer/pdb/fix.py +++ b/frustratometer/pdb/fix.py @@ -114,15 +114,26 @@ def repair_pdbs(jobs, pdb_directory: Path = None) -> list: pdb_directory = Path(tempfile.gettempdir()) pdb_directory = Path(pdb_directory) - worker_args = [] + processes = [] cleaned_paths = [] for pdb_file, chain in jobs: pdb_file = Path(pdb_file) cleaned = pdb_directory / f"{pdb_file.stem}_cleaned.pdb" cleaned_paths.append(cleaned) - worker_args.append((str(pdb_file), chain, str(cleaned))) + p = multiprocessing.Process( + target=_repair_worker, + args=(str(pdb_file), chain, str(cleaned)), + ) + processes.append((p, pdb_file)) + + for p, _ in processes: + p.start() - with multiprocessing.Pool() as pool: - pool.starmap(_repair_worker, worker_args) + for p, pdb_file in processes: + p.join() + if p.exitcode != 0: + raise RuntimeError( + f"PDB repair failed for {pdb_file.name} (exit code {p.exitcode})" + ) return cleaned_paths \ No newline at end of file diff --git a/tests/test_structure.py b/tests/test_structure.py index 2764a5de..e3968b9f 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -73,35 +73,47 @@ def test_repair_pdb_no_memory_leak(tmp_path): assert growth_mb < 200, f"Memory grew by {growth_mb:.0f} MB over 3 repairs — possible leak" -@pytest.mark.memory_heavy -def test_pdbfixer_leaks_without_isolation(tmp_path): - """Canary: calling PDBFixer in-process DOES leak memory. - - Good news: If this test starts failing, pdbfixer/OpenMM may have fixed their leak and - the multiprocessing isolation in fix.py can be removed. - """ - import gc - import resource +def _measure_pdbfixer_leak(pdb_path, out_path, result): + """Measure PDBFixer memory leak in an isolated process (child target).""" + import gc, resource from frustratometer.pdb.fix import _repair_worker - pdb = str(test_data_path / '6u5e.pdb') - out = str(tmp_path / 'cleaned.pdb') - - # Warm up - _repair_worker(pdb, 'A', out) + _repair_worker(pdb_path, 'A', out_path) gc.collect() baseline_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss for _ in range(3): - _repair_worker(pdb, 'A', out) + _repair_worker(pdb_path, 'A', out_path) gc.collect() final_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss - growth_mb = (final_kb - baseline_kb) / 1024 - # Expect significant growth (~170 MB per call) when running in-process. - # If this fails (<200 MB), the leak is fixed upstream — great news! - assert growth_mb >= 200, ( - f"Memory only grew {growth_mb:.0f} MB. PDBFixer leak may have been fixed. " + result.value = (final_kb - baseline_kb) / 1024 + + +@pytest.mark.memory_heavy +def test_pdbfixer_leaks_without_isolation(tmp_path): + """Canary: calling PDBFixer in-process DOES leak memory. + + Good news: If this test starts failing, pdbfixer/OpenMM may have fixed their leak and + the multiprocessing isolation in fix.py can be removed. + + Runs the measurement in a child process so that the rest of the test + suite cannot inflate ``ru_maxrss`` and mask the leak. + """ + import multiprocessing + + growth_mb = multiprocessing.Value('d', 0.0) + p = multiprocessing.Process( + target=_measure_pdbfixer_leak, + args=(str(test_data_path / '6u5e.pdb'), + str(tmp_path / 'cleaned.pdb'), + growth_mb), + ) + p.start() + p.join(timeout=300) + assert p.exitcode == 0, f"Measurement process failed (exit code {p.exitcode})" + assert growth_mb.value >= 200, ( + f"Memory only grew {growth_mb.value:.0f} MB. PDBFixer leak may have been fixed. " f"Consider removing multiprocessing isolation in fix.py." ) From 7d92439e06feb47ed84ad6a8d7ff096176ff443e Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Wed, 8 Apr 2026 13:48:01 -0500 Subject: [PATCH 13/28] Adds some sparse methods to optimization --- frustratometer/classes/AWSEM.py | 18 +- frustratometer/classes/DCA.py | 9 +- frustratometer/classes/Frustratometer.py | 22 +- frustratometer/optimization/optimization.py | 245 +++++++++++++++++++- tests/test_optimization.py | 54 +++++ 5 files changed, 317 insertions(+), 31 deletions(-) diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index 42e1e157..fddf876b 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -323,11 +323,19 @@ def _build_sparse(self, p, sequence_mask_contact, theta, thetaII, burial_energy, # Indicator exposure if expose: self._start_indicator_exposure(p) - self.indicators.append(theta_c) - self.indicators.append(thetaII_c * sigma_protein_c) - self.indicators.append(thetaII_c * sigma_water_c) - self.indicator_contact_i = ci - self.indicator_contact_j = cj + # Always expose dense (L, L) indicators for optimization compatibility + L = self.N + dense_theta = np.zeros((L, L)) + dense_theta[ci, cj] = theta_c + dense_protein = np.zeros((L, L)) + dense_protein[ci, cj] = thetaII_c * sigma_protein_c + dense_water = np.zeros((L, L)) + dense_water[ci, cj] = thetaII_c * sigma_water_c + self.indicators.append(dense_theta) + self.indicators.append(dense_protein) + self.indicators.append(dense_water) + self.indicator_contact_i = None + self.indicator_contact_j = None if p.k_electrostatics != 0: electrostatics_mask = frustration.compute_mask( self.distance_matrix, maximum_contact_distance=None, diff --git a/frustratometer/classes/DCA.py b/frustratometer/classes/DCA.py index d7b074c8..dc279686 100644 --- a/frustratometer/classes/DCA.py +++ b/frustratometer/classes/DCA.py @@ -93,11 +93,10 @@ def _reformat_potts_model(self, potts_model: dict): def _apply_sparse_potts_model(self, potts_model: dict, sparse: bool): """Store potts_model in sparse or dense form. DCA has no electrostatics.""" - can_sparse = (sparse - and self._distance_cutoff is not None - and 'J' in potts_model - and potts_model['J'].shape[0] == self.mask.shape[0]) - if can_sparse: + if (sparse + and self._distance_cutoff is not None + and 'J' in potts_model + and potts_model['J'].shape[0] == self.mask.shape[0]): self.sparse_potts_model = frustration.potts_model_dense_to_sparse(potts_model, self.mask) self._potts_model = {'h': potts_model['h'], 'J': None} else: diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index 2f2c5199..b13657ac 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -46,6 +46,11 @@ def _ensure_dense_potts_model(self): if self._potts_model.get('J') is None and getattr(self, 'sparse_potts_model', None) is not None: self._potts_model['J'] = frustration.potts_model_sparse_to_dense(self.sparse_potts_model)['J'] + @property + def _is_sparse(self): + """True when a sparse Potts model is available.""" + return getattr(self, 'sparse_potts_model', None) is not None + @property def potts_model(self): """Access the Potts model dict with auto-reconstruction of J from sparse if needed.""" @@ -76,14 +81,14 @@ def native_energy(self,sequence:str = None,ignore_couplings_of_gaps:bool=False,i if sequence is None: sequence=self.sequence else: - if getattr(self, 'sparse_potts_model', None) is not None: + if self._is_sparse: energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) if getattr(self, '_elec_data', None) is not None: energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) return energy return frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) if not self._native_energy: - if getattr(self, 'sparse_potts_model', None) is not None: + if self._is_sparse: self._native_energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) if getattr(self, '_elec_data', None) is not None: self._native_energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) @@ -114,7 +119,7 @@ def sequences_energies(self, sequences:np.array, split_couplings_and_fields:bool output (if split_couplings_and_fields==True): np.array Array containing computed fields and couplings energies of the protein sequences. """ - if getattr(self, 'sparse_potts_model', None) is not None: + if self._is_sparse: output=frustration.compute_sequences_energy_sparse(sequences, self.sparse_potts_model, split_couplings_and_fields) else: output=frustration.compute_sequences_energy(sequences, self.potts_model, self.mask, split_couplings_and_fields) @@ -167,7 +172,7 @@ def couplings_energy(self, sequence:str = None,ignore_couplings_of_gaps:bool = F """ if sequence is None: sequence=self.sequence - if getattr(self, 'sparse_potts_model', None) is not None: + if self._is_sparse: couplings_energy=frustration.compute_couplings_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps) if getattr(self, '_elec_data', None) is not None: couplings_energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) @@ -200,9 +205,8 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: if not isinstance(mask, np.ndarray): mask=self.mask # Use sparse path when available - _use_sparse = getattr(self, 'sparse_potts_model', None) is not None - _elec_data = getattr(self, '_elec_data', None) - if _use_sparse: + if self._is_sparse: + _elec_data = getattr(self, '_elec_data', None) if kind == 'singleresidue': fluctuation = frustration.compute_singleresidue_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model) if _elec_data is not None: @@ -270,7 +274,7 @@ def scores(self): corr_norm : np.array Contact score matrix (N x N) """ - if getattr(self, 'sparse_potts_model', None) is not None: + if self._is_sparse: logging.warning( "scores() called on a sparse model: non-contact couplings are " "zero in sparse mode, so scores may differ from the full model. " @@ -316,7 +320,7 @@ def frustration(self, sequence:str = None, kind:str = 'singleresidue', mask:np.a if aa_freq is None: aa_freq = self.contact_freq # Sparse decoy fluctuation has shape (N_contacts, 21, 21) — use sparse pair frustration, then densify - _use_sparse = getattr(self, 'sparse_potts_model', None) is not None + _use_sparse = self._is_sparse if _use_sparse and decoy_fluctuation.ndim == 3: sparse_frust = frustration.compute_pair_frustration_sparse(decoy_fluctuation, aa_freq, correction) frustration_values = frustration.sparse_frustration_to_dense( diff --git a/frustratometer/optimization/optimization.py b/frustratometer/optimization/optimization.py index 0bdc5e59..181ab6ff 100644 --- a/frustratometer/optimization/optimization.py +++ b/frustratometer/optimization/optimization.py @@ -17,6 +17,7 @@ _AA = '-ACDEFGHIKLMNPQRSTVWY' + def index_to_sequence(seq_index, alphabet): """Converts sequence index array back to a sequence string.""" seq = ''.join([alphabet[index] for index in seq_index]) @@ -365,6 +366,217 @@ def regression_test(self): energy=self.compute_energy(seq_index) assert np.isclose(energy,expected_energy), f"Expected energy {expected_energy} but got {energy}" + +class AwsemEnergySparse(EnergyTerm): + """AWSEM energy term using sparse Potts model storage. + + Equivalent to AwsemEnergy but uses the sparse_potts_model (N_contacts, Q, Q) + and CSR-like contact lookup arrays instead of the dense (L, L, Q, Q) J matrix. + #TODO: Need better tests + + Requires a model created with ``sparse=True``. + """ + def __init__(self, model: Frustratometer, alphabet: str = _AA, use_numba: bool = True): + self._use_numba = use_numba + self.model = model + self.alphabet = alphabet + + spm = getattr(model, 'sparse_potts_model', None) + if spm is None: + raise ValueError( + "AwsemEnergySparse requires a model created with sparse=True. " + "Use AwsemEnergy for dense models." + ) + + self.model_h = model.potts_model['h'] + self.J_sparse = spm['J'] # (N_contacts, Q, Q) + self.contact_i = spm['contact_i'] # (N_contacts,) + self.contact_j = spm['contact_j'] # (N_contacts,) + self.L = spm['L'] + + from frustratometer.frustration.frustration import build_contact_lookup + offsets, partners, indices = build_contact_lookup(self.contact_i, self.contact_j, self.L) + self.lookup_offsets = offsets + self.lookup_partners = partners + self.lookup_indices = indices + + # Electrostatic data (if model has it) + elec_data = getattr(model, '_elec_data', None) + if elec_data is not None: + from frustratometer.frustration.frustration import _CHARGES + self.indicator_masked = elec_data['indicator'] * model.mask # (L, L) + self.elec_charges = _CHARGES.copy() # (21,) in DCA alphabet + else: + self.indicator_masked = None + self.elec_charges = None + + if alphabet != _AA: + reindex = [_AA.index(aa) for aa in alphabet] + self.model_h = self.model_h[:, reindex] + self.J_sparse = self.J_sparse[:, reindex][:, :, reindex] + if self.elec_charges is not None: + self.elec_charges = self.elec_charges[reindex] + + self.initialize_functions() + + def initialize_functions(self): + model_h = self.model_h.copy() + J_sparse = self.J_sparse.copy() + contact_i = self.contact_i.copy() + contact_j = self.contact_j.copy() + offsets = self.lookup_offsets.copy() + partners = self.lookup_partners.copy() + indices = self.lookup_indices.copy() + has_elec = self.indicator_masked is not None + indicator_masked = self.indicator_masked.copy() if has_elec else np.empty((0, 0)) + elec_charges = self.elec_charges.copy() if has_elec else np.empty(0) + + def compute_energy(seq_index: np.ndarray) -> float: + L = len(seq_index) + energy_h = 0.0 + for i in range(L): + energy_h -= model_h[i, seq_index[i]] + + energy_J = 0.0 + N = len(contact_i) + for k in range(N): + i = contact_i[k] + j = contact_j[k] + energy_J -= J_sparse[k, seq_index[i], seq_index[j]] + + energy = energy_h + energy_J / 2 + + # Electrostatic contribution + if has_elec: + energy_elec = 0.0 + for i in range(L): + qi = elec_charges[seq_index[i]] + if qi == 0.0: + continue + for j in range(L): + qj = elec_charges[seq_index[j]] + energy_elec -= indicator_masked[i, j] * qi * qj + energy += energy_elec / 2 + + return energy + + def compute_denergy_mutation(seq_index: np.ndarray, pos: int, aa_new: int) -> float: + aa_old = seq_index[pos] + if aa_old == aa_new: + return 0.0 + + # Fields contribution + delta = -model_h[pos, aa_new] + model_h[pos, aa_old] + + # Couplings: iterate over contacts involving pos + start = offsets[pos] + end = offsets[pos + 1] + for idx in range(start, end): + k = indices[idx] + nbr = partners[idx] + aa_nbr = seq_index[nbr] + if contact_i[k] == pos: + delta += J_sparse[k, aa_old, aa_nbr] - J_sparse[k, aa_new, aa_nbr] + else: + delta += J_sparse[k, aa_nbr, aa_old] - J_sparse[k, aa_nbr, aa_new] + + # Electrostatic mutation correction + if has_elec: + dq = elec_charges[aa_new] - elec_charges[aa_old] + if dq != 0.0: + L = len(seq_index) + phi_pos = 0.0 + for j in range(L): + phi_pos += indicator_masked[pos, j] * elec_charges[seq_index[j]] + delta -= dq * phi_pos + + return delta + + def compute_denergy_swap(seq_index: np.ndarray, pos1: int, pos2: int) -> float: + aa1_old = seq_index[pos1] + aa2_old = seq_index[pos2] + if aa1_old == aa2_old: + return 0.0 + + aa1_new = aa2_old # pos1 gets pos2's aa + aa2_new = aa1_old # pos2 gets pos1's aa + + delta = 0.0 + # Fields + delta -= model_h[pos1, aa1_new] - model_h[pos1, aa1_old] + delta -= model_h[pos2, aa2_new] - model_h[pos2, aa2_old] + + # Couplings for pos1 + start1 = offsets[pos1] + end1 = offsets[pos1 + 1] + for idx in range(start1, end1): + k = indices[idx] + nbr = partners[idx] + if nbr == pos2: + continue # handled separately below + aa_nbr = seq_index[nbr] + if contact_i[k] == pos1: + delta += J_sparse[k, aa1_old, aa_nbr] - J_sparse[k, aa1_new, aa_nbr] + else: + delta += J_sparse[k, aa_nbr, aa1_old] - J_sparse[k, aa_nbr, aa1_new] + + # Couplings for pos2 + start2 = offsets[pos2] + end2 = offsets[pos2 + 1] + for idx in range(start2, end2): + k = indices[idx] + nbr = partners[idx] + if nbr == pos1: + continue # handled separately below + aa_nbr = seq_index[nbr] + if contact_i[k] == pos2: + delta += J_sparse[k, aa2_old, aa_nbr] - J_sparse[k, aa2_new, aa_nbr] + else: + delta += J_sparse[k, aa_nbr, aa2_old] - J_sparse[k, aa_nbr, aa2_new] + + # Direct interaction between pos1 and pos2 + start = offsets[pos1] + end = offsets[pos1 + 1] + for idx in range(start, end): + k = indices[idx] + nbr = partners[idx] + if nbr == pos2: + if contact_i[k] == pos1: + delta += J_sparse[k, aa1_old, aa2_old] - J_sparse[k, aa1_new, aa2_new] + else: + delta += J_sparse[k, aa2_old, aa1_old] - J_sparse[k, aa2_new, aa1_new] + break + + # Electrostatic swap correction + if has_elec: + dq1 = elec_charges[aa1_new] - elec_charges[aa1_old] + dq2 = elec_charges[aa2_new] - elec_charges[aa2_old] + if dq1 != 0.0 or dq2 != 0.0: + L = len(seq_index) + phi1 = 0.0 + phi2 = 0.0 + for j in range(L): + qj = elec_charges[seq_index[j]] + phi1 += indicator_masked[pos1, j] * qj + phi2 += indicator_masked[pos2, j] * qj + delta -= dq1 * phi1 + dq2 * phi2 + # Correct double-counting: both positions change simultaneously, + # but each phi assumed the other kept its old charge. + delta -= indicator_masked[pos1, pos2] * dq1 * dq2 + + return delta + + self.compute_energy = compute_energy + self.compute_denergy_mutation = compute_denergy_mutation + self.compute_denergy_swap = compute_denergy_swap + + def regression_test(self): + expected_energy = self.model.native_energy() + seq_index = sequence_to_index(self.model.sequence, alphabet=self.alphabet) + energy = self.compute_energy(seq_index) + assert np.isclose(energy, expected_energy), f"Expected energy {expected_energy} but got {energy}" + + class AwsemEnergyAverage(EnergyTerm): def __init__(self, model:Frustratometer, use_numba=True, alphabet=_AA): self._use_numba=use_numba @@ -373,16 +585,16 @@ def __init__(self, model:Frustratometer, use_numba=True, alphabet=_AA): self.reindex_dca=[_AA.index(aa) for aa in alphabet] assert "indicators" in model.__dict__.keys(), "Indicator functions were not exposed. Initialize AWSEM function with `expose_indicator_functions=True` first." - self.indicators = model.indicators + self.indicators = list(model.indicators) self.alphabet_size=len(alphabet) self.model=model - self.model_h = model.potts_model['h'][:,self.reindex_dca] - self.model_J = model.potts_model['J'][:,:,self.reindex_dca][:,:,:,self.reindex_dca] + self.model_h = model._potts_model['h'][:,self.reindex_dca] self.mask = model.mask self.indicators1D=np.array([ind for ind in self.indicators if len(ind.shape)==1]) self.indicators2D=np.array([ind for ind in self.indicators if len(ind.shape)==2]) #TODO: Fix the gamma matrix to account for elecrostatics self.gamma = np.concatenate([(a[self.reindex_dca].ravel() if len(a.shape)==1 else a[self.reindex_dca][:,self.reindex_dca].ravel()) for a in model.gamma_array]) + self._is_sparse = model._is_sparse self.initialize_functions() @@ -483,7 +695,10 @@ def denergy_mutation(seq_index, pos, aa): self.compute_energy = compute_energy self.compute_denergy_mutation = denergy_mutation - awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function + if self._is_sparse: + awsem_energy = AwsemEnergySparse(model=self.model, alphabet=self.alphabet).compute_energy + else: + awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function def compute_energy_sample(seq_index,n_decoys=100000): """ Function to compute the variance of the energy of permutations of a sequence using random shuffling. @@ -520,16 +735,16 @@ def __init__(self, model:Frustratometer, use_numba=True, alphabet=_AA): self.reindex_dca=[_AA.index(aa) for aa in alphabet] assert "indicators" in model.__dict__.keys(), "Indicator functions were not exposed. Initialize AWSEM function with `expose_indicator_functions=True` first." - self.indicators = model.indicators + self.indicators = list(model.indicators) self.alphabet_size=len(alphabet) self.model=model - self.model_h = model.potts_model['h'][:,self.reindex_dca] - self.model_J = model.potts_model['J'][:,:,self.reindex_dca][:,:,:,self.reindex_dca] + self.model_h = model._potts_model['h'][:,self.reindex_dca] self.mask = model.mask self.indicators1D=np.array([ind for ind in self.indicators if len(ind.shape)==1]) self.indicators2D=np.array([ind for ind in self.indicators if len(ind.shape)==2]) #TODO: Fix the gamma matrix to account for elecrostatics self.gamma = np.concatenate([(a[self.reindex_dca].ravel() if len(a.shape)==1 else a[self.reindex_dca][:,self.reindex_dca].ravel()) for a in model.gamma_array]) + self._is_sparse = model._is_sparse self.initialize_functions() @@ -668,7 +883,10 @@ def denergy_mutation(seq_index, pos, aa): self.compute_energy = compute_energy self.compute_denergy_mutation = denergy_mutation - awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function + if self._is_sparse: + awsem_energy = AwsemEnergySparse(model=self.model, alphabet=self.alphabet).compute_energy + else: + awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function def compute_energy_sample(seq_index,n_decoys=100000): """ Function to compute the variance of the energy of permutations of a sequence using random shuffling. @@ -707,16 +925,16 @@ def __init__(self, model:Frustratometer, use_numba=True, alphabet=_AA, n_decoys= self.n_decoys=n_decoys assert "indicators" in model.__dict__.keys(), "Indicator functions were not exposed. Initialize AWSEM function with `expose_indicator_functions=True` first." - self.indicators = model.indicators + self.indicators = list(model.indicators) self.alphabet_size=len(alphabet) self.model=model - self.model_h = model.potts_model['h'][:,self.reindex_dca] - self.model_J = model.potts_model['J'][:,:,self.reindex_dca][:,:,:,self.reindex_dca] + self.model_h = model._potts_model['h'][:,self.reindex_dca] self.mask = model.mask self.indicators1D=np.array([ind for ind in self.indicators if len(ind.shape)==1]) self.indicators2D=np.array([ind for ind in self.indicators if len(ind.shape)==2]) #TODO: Fix the gamma matrix to account for elecrostatics self.gamma = np.concatenate([(a[self.reindex_dca].ravel() if len(a.shape)==1 else a[self.reindex_dca][:,self.reindex_dca].ravel()) for a in model.gamma_array]) + self._is_sparse = model._is_sparse self.initialize_functions() @@ -742,7 +960,10 @@ def initialize_functions(self): region_means=compute_all_region_means(indicators1D,indicators2D) # indicator_means*=0 # Set indicator means to zero to check if the problem is with the mean phi or the inner product matrix - awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function + if self._is_sparse: + awsem_energy = AwsemEnergySparse(model=self.model, alphabet=self.alphabet).compute_energy + else: + awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function if self.n_decoys: n_decoys=self.n_decoys diff --git a/tests/test_optimization.py b/tests/test_optimization.py index b3ad765a..485f95ef 100644 --- a/tests/test_optimization.py +++ b/tests/test_optimization.py @@ -374,6 +374,15 @@ def model(request): model = AWSEM(structure, distance_cutoff_contact=distance_cutoff_contact, min_sequence_separation_contact=min_sequence_separation_contact, expose_indicator_functions=True, k_electrostatics=k_electrostatics, sparse=False) return model +#"distance_cutoff_contact", "min_sequence_separation_contact", "k_electrostatics" +@pytest.fixture(scope="module", params=[(10, 2, 0.0), (10, 2, 4.15)]) +def sparse_model(request): + native_pdb = "tests/data/1bfz.pdb" + distance_cutoff_contact, min_sequence_separation_contact, k_electrostatics = request.param + structure = Structure.full_pdb(native_pdb, "A") + model = AWSEM(structure, distance_cutoff_contact=distance_cutoff_contact, min_sequence_separation_contact=min_sequence_separation_contact, expose_indicator_functions=True, k_electrostatics=k_electrostatics, sparse=True) + return model + @pytest.mark.parametrize("reduced_alphabet,use_numba", [ (_AA, True), (_AA, False), (_AB, False), (_AC, False), ]) @@ -392,6 +401,51 @@ def test_awsem_energy(model,reduced_alphabet,use_numba): awsem_energy.test(seq_indices[0]) awsem_energy.regression_test() +@pytest.mark.parametrize("reduced_alphabet,use_numba", [ + (_AA, True), (_AA, False), (_AB, False), (_AC, False), +]) +def test_awsem_energy_sparse(sparse_model, reduced_alphabet, use_numba): + seq_indices = np.random.randint(0, len(reduced_alphabet), size=(1, len(sparse_model.sequence))) + awsem_energy = AwsemEnergySparse(use_numba=use_numba, model=sparse_model, alphabet=reduced_alphabet) + awsem_energy.test(seq_indices[0]) + awsem_energy.regression_test() + +@pytest.mark.parametrize("reduced_alphabet", [_AA, _AB, _AC]) +def test_awsem_energy_sparse_matches_dense(reduced_alphabet): + """Verify that AwsemEnergySparse and AwsemEnergy produce the same energy values.""" + native_pdb = "tests/data/1bfz.pdb" + structure = Structure.full_pdb(native_pdb, "A") + dense_model = AWSEM(structure, distance_cutoff_contact=10, min_sequence_separation_contact=2, expose_indicator_functions=True, k_electrostatics=4.15, sparse=False) + sparse_model = AWSEM(structure, distance_cutoff_contact=10, min_sequence_separation_contact=2, expose_indicator_functions=True, k_electrostatics=4.15, sparse=True) + + dense_energy = AwsemEnergy(model=dense_model, alphabet=reduced_alphabet) + sparse_energy = AwsemEnergySparse(model=sparse_model, alphabet=reduced_alphabet) + + seq_index = sequence_to_index(dense_model.sequence, reduced_alphabet) + assert np.isclose(dense_energy.compute_energy(seq_index), sparse_energy.compute_energy(seq_index)), \ + "Sparse and dense native energies differ" + + # Check a random permutation too + shuffled = seq_index.copy() + np.random.shuffle(shuffled) + assert np.isclose(dense_energy.compute_energy(shuffled), sparse_energy.compute_energy(shuffled)), \ + "Sparse and dense shuffled energies differ" + + # Check denergy_mutation + pos = min(5, len(seq_index) - 1) + aa_new = (seq_index[pos] + 1) % len(reduced_alphabet) + assert np.isclose( + dense_energy.compute_denergy_mutation(seq_index, pos, aa_new), + sparse_energy.compute_denergy_mutation(seq_index, pos, aa_new), + ), "Sparse and dense denergy_mutation differ" + + # Check denergy_swap + p1, p2 = min(2, len(seq_index) - 1), min(7, len(seq_index) - 1) + assert np.isclose( + dense_energy.compute_denergy_swap(seq_index, p1, p2), + sparse_energy.compute_denergy_swap(seq_index, p1, p2), + ), "Sparse and dense denergy_swap differ" + @pytest.mark.parametrize("reduced_alphabet,use_numba", [ (_AA, True), (_AA, False), (_AB, False), (_AC, False), ]) From f5392444a83001da150a150889d258906ee50188 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Wed, 8 Apr 2026 12:45:27 -0500 Subject: [PATCH 14/28] Reduces dca test size --- .../data/PF09696.12_gaps_filtered_small.fasta | 1000 ++++ .../PF11976_test_filtered_alignment_small.sto | 1000 ++++ .../data/protein-matching-PF11976_small.fasta | 4022 +++++++++++++++++ tests/test_dca_frustratometer.py | 62 +- 4 files changed, 6058 insertions(+), 26 deletions(-) create mode 100644 tests/data/PF09696.12_gaps_filtered_small.fasta create mode 100644 tests/data/PF11976_test_filtered_alignment_small.sto create mode 100644 tests/data/protein-matching-PF11976_small.fasta diff --git a/tests/data/PF09696.12_gaps_filtered_small.fasta b/tests/data/PF09696.12_gaps_filtered_small.fasta new file mode 100644 index 00000000..e006b959 --- /dev/null +++ b/tests/data/PF09696.12_gaps_filtered_small.fasta @@ -0,0 +1,1000 @@ +>A0A3B3X8K4.1/48-115 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLEKPFAVLTKHSGHSQDTDAA-----GPSSSSSFSSTSYSVSALIKRKLIFKTRPKPI +>A0A4U7ARA3.1/24-162 +LLQTPSGLAIVELQGTINFPSATDSESEPDTRTDDPGSDSASQDQATQVGKLVFPLYDAEAADEKWMKRVHFYVGPHQRMTGEVKKLGKPVAVIRRRQNGEGQ-------------EGEAEREELEIVEVVKYKIVFASRPEPV +>A0A117DXJ6.1/24-158 +LLQTPSGLALLELQGTINIPSQENSESNDSSSPDGPGNPNGAPVFETPIGKLMFPDYSPQFTDTKWMKRVYLYVGRYQRMTGEVKKLPQPLAIVQRRQKELG--------------AAADDKEELEIVEIVKYKIYFKSRPEPV +>A0A6U0RHI1.1/36-110 +--------------------------------------------SKVELGGIRF----------STDGSPTMTIASH-ELKGKICDLKQPLVVLKKRKRSKGD------------DDGVNESIEYEIAGVIKKKILFDKYPK-- +>M2MJ41.1/24-138 +LLQTPSGLALVEIQGTINSTSVSDDTPAQA---------------ALDVGRLVFPYHNPENEDTSWQKRVYLYVGKHQRLTGEVKKLAKPIAVIRRKTPAT---------------SAVPDGDELEIAEIVYYKLLFAHRPEPV +>A5E2J2.1/34-169 +-VMTPHGLAVLEIQGELNLPDHRPVGTTQTPTSDSPYITVDDIYDAVKFGHLEF--------DKKDESKVTLFIGKSQRLIGNIVKLDTPLGLLKIPLSGANGMNLEDDQNDKDKDDASESTEKVQMIDIIKAKMIFKHRPLPI +>A0A136JJS0.1/25-148 +VLQTPAGLAMLELQGTINLPQAADPEDDTP---------------ETLIGSLSFPDWRPETQSTAWMKRVHLFIGQNQRLTGEVKKLPKAVAILRKRQANADVAM--------EDGASVTPAEDLEVVEIVKYKLMFSHRPEPV +>A0A4U0VS57.1/25-158 +LLHTPSGLAILELQGSINVPAAPSQTSGLTS-----DEQHAGYTNETPVGRLAFPAYSAANPDTAWMKRVYLYVGKHQRLAGEVKKLAKPLAVICRRVGPAADV-------ETMAVDGVSNEEELEIAEIVRFKVIFSQRPEPV +>A2E731.1/45-93 +--------------------------------------------------------------------SATLTIGNH-YLKGKVHRLKKPLCVMRRG-----------------------SESGIQIVSVIRKKVIFSDRP--- +>A0A1V6UY16.1/29-147 +LLQTPSGLALLELQGTINVPTGNEEDIDYST------TTENAATFETPIGKLIFPDYSVHNSDTKWMKRAYMYVGRYQRMTGEVKKLPRPIAVLQKR--------------------QASEGEELEVVEIVRYKIFFKSRPEPV +>A0A6U3EEZ6.1/28-128 +------EWAMIEINGEILQPTESTTPKDKEN-----HPQSDATKDQVELGSLWF----------DANEVPHMIVGTH-ELKGKVETLKQPFCVLEKE-------------------SSTLSTTSYAVQGIISRKILFSQYPK-- +>A0A2G5BG60.1/45-105 +----------------------------------------------------------------LDGDKVHMKIGVH-RVQGSVVKLKKPFAVLKKR-SDEC---------------TTTSDVCYDIEAIIKEKIIFKMRPD-- +>A0A1D2A400.1/42-102 +--------------------------------------------------------------STSSTGSIFLTIGYH-QLEGSRVPLKKPFAILEKD--------------------TSEGSTGYQVVGVVREKYKFSARPRPL +>A0A6U9Q805.1/46-119 +----------------------------------------------------------------NGKDAPQLYIGHH-MLKGKVEKLKAPFALLRKHKTTEDDVLGEGQTPPP---PPQGPNVHYTIDGIIRRKFIFTTRPT-- +>A0A507AT14.1/25-156 +LLQTPVGLALLELQGTINLPGGEDTGGSGVS----------QQGSAVPIGRLDFPDYREDALSTAWMKRVYMYVGQHQRLTGEVKKLPKPLAVIRRKGA-----DGVPASATATEEEDADRVEELEVVEIVKYKLMFSQRPEPV +>A0A1A8BM60.1/52-125 +----------------------------------------------------------------------VLIVGHH-ILYGKLVKLEKPFAVLRKHSGDSPDSYADDATQIPMETHQGLTSTSYTVSALIKQKLIFKTRPKPI +>A0A2H3E7A9.1/28-134 +------ETVLIELQGALDVESNHESERNGNL-----------------VGKLTI---------DEAMKKPTLRIGHH-HLEGKIVTLPKAIAVIQKSSYIRNSEDDA----MVCDEDTNGGSISWHAIAIVKRKIVFSKRPMPI +>A0A1E1LHU5.1/24-157 +LLQTPSGLALLEMQGTINLPSFDDEESISTE------SQSGIASQETPIGRLIFPDYDPAADDAAWMKRVYLYVGKHQRLTGEVKKLPKALAVIRKRNGGEEGEGQV------DNDEDEERVEQLEVVEIVKYKILFSIRPEPV +>A0A5N6J5W7.1/23-152 +VLQTPTGLAILELQGTINLPSQEAEDESTTS--TNDTHDPSIPTFETPVGKLMFPDYSPHRTDTKWMKRVYLYVGRYQRMTGEVKKLAQPLALVQRRQKET---------------TSDSDGEELEIVEIIKYKLFFKNRPEPV +>A0A1V6Z9I2.1/30-149 +LLQTPSGLALLELQGTINVPSGNEEDDIDYS-----SMDIPASTFETPIGKLMFPDYSVHNPDTKWMKRAYMYIGRYQRMTGEVKKLPRPIAVLRKR--------------------QASEDEELEVVEIVRYKIFFKSRPEPV +>G2XA02.1/24-141 +-IQTPSGLALLELQGIINLPEDAVDSDGKAT-------------KSIPVGRIDFPDYHPDTQSTAWMKRVYLYVGPHQRLTGEVKKLPRAIAIVRKKDGV---------------SNGPDGEEQLEVAEIVKYKLVFSHRPEPV +>A0A2K0WLR4.1/22-140 +LLQTPSGLALLELQGTINLPQDANGDALG----------------GIQVGRLDFPDFVIGTEGSAWMKRVHLYVGQHQRLTGEIKKLPKAMAVVRKRENKVIPGSGG---------ETLEQGKNLEVVEIVKYKLMFPNRPEPV +>A0A6T7VRB3.1/46-118 +------------------------------------------------------------------PKNIKVTVGYH-EIEGSLIALKKPVALLRSRFATSDEE-ATPM-QTSDDNDEAKVCEGFDIIGIVRKKYMFKHRPK-- +>A0A6P7MXS4.1/52-130 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLEKPFAVLTKHSSQSPDTPSGRDDDSSSVDAGGPTDTSYSVTALIKRKLIFKTRPKPI +>A0A1L7WIM0.1/24-158 +LLQTPSGLALLELQGTINLPAPDEEDMPSAD------RAGSDTPRETAIGRLVFPEYDPQNTSTGWMKRVYMYVGKHQRLTGEVKKLPKAIAVIRKRRNESAGDM----DVDMNDEGDEEGVAELEVVEIVKYKIIFSTRPEPV +>A0A409VD66.1/53-156 +------------------------------------------------VGKLKI---------DEATNKPTLLIGHH-LLEGKIATIPKPYAILVRTGPMRNAEQQSLSEEIDEDAMGEGSGAGWSVAAIVKKKVIFSKRPMPV +>A0A1L7V085.1/22-140 +LLQTPSGLALLELQGTINLPQDANGDALG----------------GVQVGRLDFPDFVMGTEGSAWMKRVHLYVGQHQRLTGEIKKLPKAMAVVRKRENKVISGSGG---------ETLEQGENLEVVEIVKYKLMFPNRPEPV +>A0A6P6AJ73.1/584-662 +--------------------------------------------QNLRIGQLCR---------PSSQENYTFTVGYH-ELTGSKVALKKPMLVLKKIKCMGTDQS---------DEATSSSRVELDVVGIIRHKILFKNRPK-- +>Q16JU5.1/48-153 +--------------------------------------------------------------------QPILIIGHH-ILQGRLQKVDKPLLVMEKCETRKRHITEPSNEEDDEENEKTVPKTEYLVRAVVKHKILFKARPKPI +>A0A6P4DFA0.1/52-118 +----------------------------------------------------------------SSQEVYTLTIGYH-ELTGSKVPLKKPMMVLKKVKHSPLDRG----------ESSGCGEIELQVVGIIRHRILFKNRPK-- +>A0A6T3S7L6.1/44-105 +-------------------------------------------------------------------SQVTLTNGPR-TLYGKVQELPKPLVLMERTGRSEPY------------KDTGRESAVLKAHGVVRKKAIFQQRPE-- +>A0A6V3EPY7.1/20-141 +------EWVMIELNGELSKPLDESRRTSQAA--ASLPGAVDDSRRRVELGSVKF--------D--ADGAPTVIIGNH-QLKGTAITLKEPFAVLRKRKASQITKNGDSEGTSEAK-LKSHCGVQLDVVGVVKRKLMFDKYPK-- +>A0A2S7YJV6.1/24-144 +LIQTPSGLALLELQGAINLPQGKDGAPLPG----------------LQIGRVEFPDHDPAAPDTAWMKRVHMFVGQHQRLTGEVKKLPRAVAVVRRRENRMEYGSGG---------AHMEEGENLEVVEIIKYKLMFGNRPEPV +>E7A1H5.1/178-222 +---------------------------------------------------------------------------------------------------QQGSAKQGKEEEDDDDAEEPQTAVYYDVVSVIKRKILFSKRPEPI +>A0A2I4FG86.1/50-116 +------------------------------------------------------------------QEVYTFTVGYH-ELTGSKVSLKKPLLVLKKTKHSDPDHE--------IGEGDFSSRVELEVIGVIRHRILFKTRPK-- +>A0A084QAZ6.1/26-139 +LLQTPSGLALLELQGAINQPHDAKGELVP----------------DVEIGRLDFPDHDPSAPDAAGTRRVHMYIGQHQRLAGEVRKLPKAIAVVRRRRRQG---------------EAGEQGDDLEVVEIVKHKLLFSNRPEPV +>A0A5S6QZF9.1/49-102 +---------------------------------------------------------------------PFLVIGRQ-ILYGEVVTLPKPVVALRKK------------------AASETDRRGYDIVSVVRSKICFKTRPK-- +>A0A1V4K1Q1.1/51-109 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKQGAG--------------ESQAAGPHTCYTVTALIKTKLLFKTRPKPI +>V5FP12.1/26-163 +LLQTPSGLAILELQGTINIPSPGEDQDTDEG-MNMDLSQGPEASVETPIGKLMFPEYSPQNPDTKWMKRVYLYIGKYQRMTGEVKKLPKPLAVIQRRQRPDAGDG-------NTTNAGTDTEDELEIVEIVKYKILFGSRPEPL +>M2Y3R0.1/14-96 +------DWILLELQGSFHLNEQSTHQSLHRI-------EETTQLGGLNIGDLWV---------NWEQATAKLRVGNS-LLQGKVESLKKPFAVLKKEANGKENQA------------------S-------------------- +>A0A286XDH6.1/51-114 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPEEQDCD---------ELGHETGTTRYLVTALIKDKILFKTRPKPI +>E9EPW9.1/22-140 +LIQTPSGLALLELQGTINLPQSKDGQALS----------------GIEIGRIDFPDFVPDAEGSAWMKRVHMYVGQHQRLTGEVKKLPKAIAVISRRENRVLENSAG---------TYLEEGENLEVVEIVKYKIMFSNRPEPV +>A0A672FFZ3.1/48-123 +----------------------------------------------------------------------VLIVGHH-ILYGKQVRLEKPFAVLTKHSGQSQDSGHDDDGDAPVAMEEGPASTSYSVSALIKRKLIFKTRPKPI +>A0A4Q1BW09.1/59-117 +-------------------------------------------------------------------DKPTLHLGPHHLLHGKIVSLPKPLAVIRKSHAPIAT-THKADVHSDRNTRE-------------------------- +>A0A0W0CXT7.1/109-132 +------------------------------------------------------------------------------------------------------------------------EGKNVEMLDIIEYKVIFSDRPLPI +>A0A1E1X062.1/55-111 +----------------------------------------------------------------------VLLVGHH-ILYGKEQDIEKPFLVIAKSTA----------------EAEPPRAKEYLVRGIVTRKIIFRSRPKPI +>A0A0D2B517.1/24-148 +LLQTPSGLALLELQGTFHVPASSSQADDVDP----SGDANFDQGIATSVGRLLFPAYSSSAPDTAWMKRVYLYVGKHQRLTGEVKKLPKPMGILRRRPK-----------------ASTEDADELEIVEVVRHKIVFSTRPEPV +>A0A4T0DB77.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A6T6C2J5.1/6-121 +--------LIIELQGRVEICEVLGEGFTRAADPLRRVRMTNASPSGVHIGVLTQ----------SNAEQYELVIGNH-RLEGVLRELPSPLLISEKKVA---------------SIRESQCLVKWVICGVAEKSLVFESRPKPV +>J3MWA9.1/82-152 +-----------------------------------------------HIGRLCA------AASPSSKAAFTFTVGYH-ELAGTKVTLKKPLLVLRKQK-----------------TSTTTAETELEVIGVIRHKILFKDRPK-- +>A0A448YSD7.1/27-148 +VVSTNSGLALVEIQGELNLPAKKPEGLKEEEVPSIYSDVNDPTVDLVKFGRLEL---------DERSGHAVLFISTSQRLEGKVEKLDHPLGILRIS---------------------REGDEMCELLDVIERRVVFRNRPLPI +>A0A177VDL5.1/82-126 +---------------------------------------------------------------------------------------------------TGTGGNKRKRRRQQQGNSERKPRVWYDVVCLIRRKILFSQRPEPV +>A0A3D8RNT1.1/24-149 +LLQTPSGLALLELQGTINLPSHSTSSSSDEQ---------------VAIGRLIFPHYDPASQDTSWMKRVYMYVGKHQRLTGEVKKLPKPMAVIRKRVIEDNSAGSG------DLAEGEDRSEELEIVEIIKWKILFSLRPEPV +>A0A2T0ACK2.1/34-151 +-----SQPFLLELQGILEPPSDEKGAEEAG-------EAAAASMEGVRVGKVDL----------ADPKKPVLRIAHH-RLEGKVEKLLTPYALLRTTRSGSCSSPDHDDT---ADSRSPKHQPQISIAALITHKLVFSRRPEPL +>A0A1V6QEI8.1/30-152 +LLQTPTGLAILELQGTINVPTSNEDEMTDSP---NPNAPNPASTFETPIGKLMFPDYSVHNPDTKWMKRAYLYVGRYQRMTGEVKKLPRPIAVLQRH-------------------QGEGGGEELEVVEIVRYKIFFKSRPEPV +>A0A4Y7JCE6.1/283-363 +---------------------------------------------------------------TSSEENYTFTVGYH-ELSGTKMKLKKPYLILKKKRTILESIPDDEEEEEDISKASPKTETELEVIGIIRHRILFKTRPKPL +>H2XRH0.1/44-103 +-----------------------------------------------------------------SKGDPIMIIGHH-ILYGKVKKLEKPFAVLVKN------------------KDAEMDQREYLIKAVITNKLIFSLRPKPI +>A0A1G4IZR8.1/25-130 +-ITTPFGNMLLEIQGDLDFPAESPRYDPQRI------FSKYQDDQIVRFGRLII---------EADYKKATLYIGEKQRLLGSIMKLETPLGLLKFN----------------------QDSTTVELEDIIQFKIIFKDRPLPI +>A0A446T1N5.1/82-151 +-------------------------------------------------------------------GGYTFTVGYH-ELAGSKVTLKKPLLVLRKKKNDKGN-PGELG---QGGQAAAAAEVELEVIGIIRHKILFKDRPK-- +>H8X0M2.1/32-166 +LITTPYGLALLEIQGELNLPHTKPDIPLNQLEKMKNFITVDGIYDAVKFGHLQF--------DEKDDSRVTLFIGKSQRLIGNVAKLDVPLGVLKVPLKQEARNG-HG-----DVDMDEEEEQEIQMVDIVRAKMIFKQRPLPI +>A0A0K9PG20.1/37-110 +--------------------------------------------RNLEIGRLCH--------SSCLEGSYTFTVGYH-ELTGTKMILKKPLLVLQKSKTVV---------------NGGDKRGELQIVGIIRQKILFKTRPK-- +>E9CW81.1/25-168 +LLNTPSGLAILELQGTINLPSNEPHYNDEQT------DLQSEFHAQTPIGRLVFPDYDASNPSGSWMKRVHLYVGRHQRLTGEVKKLPKPLAIIRRRQSKDSSGAGHIMRSAARDTAGNPSVEELEIAEIIRYRLLFSARPEPV +>A0A1D1XTK7.1/94-168 +-------------------------------------------IQNLEIGRLCC----------TSQANYTLTVGYH-ELSGTKQALKKPLLVLRKTKEKGPD-------------GADPPKTELQVIGVIRHRILFKTRPK-- +>A0A4Y9ZIC3.1/30-151 +-----SELALIELQGSLEVQGDRRGQTVGKL--TIDADGKVCFLTVSRFSKLIM--------HENLKGKPTLLIGYH-LLEGKVVSLSKPLAVLHCAAPSSASGDVMD------VDDSAPEPPSYEICAIVRKKLVFSKRPMPM +>A0A058ZZB2.1/38-117 +---------------------------------------------NLEIGKLCR---------PSSQEVYTFTVGYH-ELTGSKVLLKKPFLVLKKVKLMDAEQ-------SSNTDSANSPKVELEVVGIIRHRILFKTRPK-- +>A0A2W1ERM2.1/13-142 +LLHTPSGLALLEIQGTIHFPTPAPSTTS------------------TQIGKLVFPYYNPDINDTKWMKRVYMYVGKGQRMTGECKKLVNPIGVMRKRERKDGGDVEMGLEDDDKEKRNNGGEEELEIVEVVRYKIIFSSRPEPI +>A0A0K0DDW4.1/50-111 +---------------------------------------------------------------HKDKNEALLQIGHH-LLEGKASELEKPLLLMKPSP--P-N--------------QHFEERTMIVEAVIKRRLLFKNRPKP- +>A0A0E9N8Q1.1/87-162 +---------------------------------------------------------------DEQSKTAYLTVGY-QRLTGKVVDLKSPFAVLRKREGGELSMED----AEGRAADWQRGDVEMDVVEIIRKKVVFNQRPEPI +>A0A165A1I6.1/47-250 +LLHTPSGLAVIEMQGTINMPSAELVHDLDDDKHNKRPKSKAAYEAETAIGRLVFPYYSPTEPDNKWMKRVHLYVGRHQRMTGEVKKLVNPLAVIRRRQQQGPVGSGKGTANEVSEKGGDDEEEELEIVDIVRYKILFSQRPEPV +>B0WI22.1/44-149 +--------------------------------------------------------------------QPILIIGHH-ILQGRCQKIDKPLLVMEKCCTRGKQQQQRRTQDDDEDNEKTVPKTEYLVRAVVRQKVLFKARPKPI +>A0A2V2WU40.1/13-194 +-----QEMLLLELQGKVSIPPKLIREASEKQAEVSDGALGQETVVEVPLGHIDD--------DPRNKKRCSLRIGTL-LVEGSRGQFGEPLLVLRQRKSQPCQQPQHGAQKSPLSSSNEMPTKTYELVGIVERYVHLNSKPL-- +>A0A212DBY5.1/50-113 +---------------------------------------------------------------------PVLIVGHH-ILYGKIIHLERPFAVLVKHTPGQQ----------DCDALGCESGTRYLVTALIKNKILFKTRPKPI +>A0A672PNU8.1/51-116 +----------------------------------------------------------------------VLVVGHH-ILYGKQVKLEKPFAVLMKHSGLPQDEE-------ENMETNQENPTSYTVSALIKKKLIFKTRPKPI +>A0A026VRR0.1/12-102 +-------------------------------------------------GDLKFEKVENSEDHFTKTGVPILIIGIH-VLHGKEVTLEKPLFVLKKYHENVE---------NDTLSEQHGTETKYTVMAIVRKKLLFRSRPKPI +>A0A1I8A4U9.1/45-100 +-------------------------------------------------------------------GQPLLLIGHL-MLEGKLVTLDKPLGVLRPG--------------------DGETPNEVTAVAIVRRKILFKQRPRPI +>K7FRJ2.1/51-109 +----------------------------------------------------------------------VLIVGHH-ILYGKVVHLEKPFAVLTKRGARDHG--------------SPGAAAQYLVTALIKTKLLFKTRPKPI +>A0A1B7SCY5.1/30-150 +-VCTKWGSMLLEIQGELNLPPNKPEGLNEQEDFV--ADPERLVRDAVKFGKLEI---------ENDMKRATLYISTSQRLVGTVETIDPPLGLLKTD---------------------IDTSGKCEFVDVIRKKVVFKLRPLPI +>A0A0A9USG9.1/37-126 +--------------------------------------------RGLHIGRLCS---APSPSSSSSKAGYTFTVGYH-ELAGTKVTLKKPLLVLRKKKVSAAAAGGG--QEPP---PSAPAEVELEVIGVIRHKILFKDRPK-- +>V9D2L3.1/24-154 +LFQTPSGLAVVEIQGTIHGPFQDPTPEDENQ-----------VPTTRQIGRLEFPLYNPQASDGKWMKKVYLYVGKHQRLTGEIKKLGKPLAVIQKVDHSSGD----DRDANSGTNVGEANQELLEIVEIIRFKVLFSARPEPV +>A0A2I0VLB7.1/52-113 +---------------------------------------------------------------------YTFTVGYH-ELSGTKMALKKPLLVLKKKKVGDAF----------ESDSSDSSGVELEVIGIIRHRILFKTRPM-- +>A0A5Q0PNW6.1/27-161 +LLQTPSGLAILELQGTINFPATTDDDDDSDMHEEFQAEGAKTKIIETELGKIMFPDYSDLIDSTKWMKRVYLYAGRYQRMTGEVKKLAKPLAVIQRRERSTTE-------------NGNGEQDELEIVEIIKYKIIFASRPEPV +>A0A229Z560.1/24-160 +ILQTPSGLAILELQGTINLPSLDDQGAVPHPNAEDPDVDAGITAFETPIGKLMFPDYSPQTTDTKWMKRVYLYVGRYQRMTGEVKKLAQPLALVQKRKKHSDG-----------ERIAESEGEELEIVEIIKYKLLFKNRPEPV +>B3M5C2.2/47-141 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLEKPFAVLEKSKTNEGERLLDTSIATQDMTQKTRQRTEYTVRAVCTKKLIFKSRPKPI +>A0A4S8SZJ5.1/35-154 +ILHTPSGLAIIELQGTINFPQSNPTGEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A1R1X0H7.1/43-114 +--------------------------------------------------------------DLMHDGSAYLLIGTN-RLAGKIVPLKKAIAVSQKVLSHDKD-------KSSTSPNNEYVDVDYNIKAIIKYKFLFKKRPD-- +>A0A6A6TXJ4.1/26-142 +LLQTPSGLALVELQATIHTPNRVVKDDEDVA--------MDGTIPQTVVGNLSFPLYDPSTPETAWMKSVLLYIGKHQLLKGEVKKLPKAMALVRRQ--------------------DGSTSETMEIAEIVRYKIVFSQRPEPV +>A0A124GRW7.1/30-150 +LLQTPSGLALLELQGTINIPSGNEEDDLDYS----TSTDNPASTFETPIGKLMFPDYSVHNPDTKWMKRAYMYVGRYQRMTGEVKKLPRPIAVLRKR--------------------QASEGEELEVVEIVRYKIFFKSRPEPV +>A0A2P6NIF4.1/1599-1671 +----------------------------------------------------------------RVEKSVTLEIGNH-SLEGKVVTLPKPLLVTQRTEWRRYKSEIIP---DDASLLIINTQIEYHITGVIRKKFLFSTRP--- +>A0A6V3UHW5.1/79-181 +--------------------------------------------QRVELGKFYM--------SGPDQKIPTLILGSH-QVKGKVKKLKSSFCLMEKRYKNATATSTAFSS------EKKKQIECYQIIGIVTEKIIFDTYPK-- +>A0A367JZX0.1/46-100 +-----------------------------------------------------------------NENSAELVIGHH-RLVGRKVKLSKPYAVIHKR--------------------KDSMEASYDVVSIIKEKYVFSQRP--- +>A0A094GYY0.1/25-151 +LLQTPSGLALLEMQGTINTPSPPTQDEDGES--------NQPGSYETPIGRLVFPDYEPGTSGGAWQKCVYLYVGMHQRLTGEVKKLPKAIAIIRKRAPSETE----------NASKEGQGVEELEIVEIVKWKIIFSNRPEPV +>A0A091K8Z4.1/5-63 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLDKPFAVLVKQGAAEPG--------------PTGLPTRYTVTALIKTKLLFKTRPKPI +>A0A507D650.1/61-94 +----------------------------------------------------------------DDKNTPWLLVGRH-RLRGKRVKLDKPYGVMQRSDN--------------------------------------------- +>A0A078H329.1/27-113 +----------------------------------ETQSSFQGSVQNLEIGHLCH--------SDSSQETYTFTVGYH-ELTGSKVTLKKPLLVLKKLQKGTDG--------------SSKKETELEVVGIIRSKILFKTRPKPL +>A0A1Y1IAC8.1/47-112 +------------------------------------------------------------------TEKPILRIGYH-ELEGSRVVLKKALAVLRKIKLPPTAGQ-----------QIEGGSTRFDVVGVIRQKYLFKTRPRPL +>A0A6G1RRK0.1/77-135 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKREAGE--------------PSATGPHTRYAVTALIKTKLLFKTRPKPI +>A0A1Z8JQ99.1/35-158 +IVATPLGLTLVEIQGELSLPKTKPNHLNEREQLLKSIHSLHGDVDTVKFGHLEL---------DTSLNKATLFISTTQRLLGKIEKIDPPLGVLKIQ---------------------HGPETSSQIIDVINSKVIFKQRPLPI +>A0A0G2FC35.1/28-153 +LLQTPSGLALLELQGTINLPAVEGGDGPQQQ-------------QPVDIGRLDFPDYRPDSLSTTWMRRVYMYVGQHQRLTGEVKKLPRAVGVVQRRQREQRGGCGG----------GDDRAEELEVVEIVKYKIVFSSRPEPV +>A0A0A8KZQ1.1/26-132 +--ITPLGHVMIEIQGDLQHPQKSISPELDTD----SRFIQHEGKELVRFGILSY---------DLHSKNVTLFIGNKQRLVGTIIKVNPPLGLLKFD----------------------KTAGTVDLRDVIRYKIIFKNRPLPI +>A0A1E3PEG2.1/25-148 +VLKTPSGLILVEIQGVLHIPDIDHDDSGIP---------------NVLVGSFDV----------KEDGKALLMVHGHQRLEGTVKKLQTPLGILKMESEENESNRHNPDSQGRNYSTQRIQHGKAEIVEIIRHKVSFILRPEPV +>A0A4T0FAQ0.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGVSSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A6P3DQX5.1/50-126 +---------------------------------------------NVYIGDLHF----------TKSGTPILIIGIH-VLQGKEMALQKPFAVLVKKKNEETN-----------TANTSEVKTAYVIKAIVKKKLIFKSRPKPI +>A0A2C5XT89.1/49-134 +--------------------------------------------AVVEMGRLEFPDGAD-GDDTSWMKRVYLYVGRYQRLEGEVEKLPAALAVVRRREDEPDGQ-------------KKPQAASLEVVDIIKYKLIFSNRPEPV +>A0A6P8MCD1.1/50-126 +---------------------------------------------NVYIGDLHF----------TKSGTPILIIGIH-VLQGKEMALQKPFAVLVKKKNEETN-----------TANTSEVKTAYVIKAIVKKKLIFRSRPKPI +>A0A669R7W3.1/51-104 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLMKQA-------------------ADPAGTRYAVTALIKTKLLFKTRPKPI +>A0A067CDZ8.1/45-96 +--------------------------------------------------------------------VPTLLIGNH-LLEGKAAKLAKPMAIMRKD-----------------------GGAAYTVVGIARKKLIFNTRPKPV +>A0A0H5R5A5.1/59-125 +----------------------------------------------------------------QSDGVAWLTIGNH-KLQGAIETLQKPLAVASTRRHGDGE------------DIRNNANRRVEIKGFIRQKFVFRQRPFPI +>Q5BBV3.1/216-339 +LLQTPSGLALLELQGTINLPFQENLDAENES-----TDFNSPSTYETPIGKLMFPDYSQNAKDTSWMKRAYLYVGRYQRMTGEVKKLPKPLAIIQRRQT----------------DGADDAREQLEVVEIVKYKLIFKNRPEPV +>A0A3S7WPI0.1/167-226 +---------------------------------NSPSASRRAAVVEVPLGHVEQ--------DRLDEKRCTLCIDTL-RVHGSRSSFKRPWLVLRECTPARM------------------------------------------ +>B4QP79.1/40-134 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLDKPFAVLEKSKTNEGERLLETSMASQDVSMKSRQRTEYTVRAVCTKKLIFKSRPKPI +>A0A0J0A438.1/22-140 +LLQTPSGLALLELQGTINLPQDANGDALG----------------GVQVGRLDFPDFVMGTEDSAWMKRVHLYVGQHQRLTGEIKKLPKAMAVVRKRENKVISGSGG---------ETLEQGENLEVVEIVKYKLMFPNRPEPV +>R0GSA4.1/30-111 +-------------------------------------ASFEGSIQNLEIGRLCH--------TESSQETYTFTVGYH-ELIGSKVTLKKPLLVLKKLQLD----------------EDSGKGTELEVVGIIRTKILFKTRPKPL +>A0A6F8ZSS8.1/7-72 +----------------------------------------------------------------------VLIVGHH-ILYGKVVKLEKPFAVLMKHSGLPQGEEVP-------METNQQNPTTYSVSALIKKKLIFKTRPKPI +>A0A0M9VPR0.1/63-91 +-------------------------------------------------------------------------------------------------------------------AKRLPTSTSYSVVTIIRKKILFSKRPEPI +>A0A2S4KQ73.1/23-141 +LLQTPSGLALLELQGTVNLPSDANGETLK----------------DVEVGRLEFPDHVPGAEGSAWMKRVHLYIGQHQRLTGEVKKLPRAMAVVRRRENRWYENSAG---------PVQEQGDNLEVVEIVQYKLMFSNRPEPV +>A0A163JW42.1/42-114 +---------------------------------------------------IHV-----------DKDKAYVLIGHH-RIEGVRKKLAKPLAVIHKRGTTTTDSDAM------DLDQQEGMATEYNVTTIIKEKIVFTNRPR-- +>A0A1Y2ERG6.1/57-140 +----------------------------------------------------------------EPDGRIFLYVGY-QKMEGKLIKLKKPFAVLKRPTSAAPSASDNDAVMSSQIMSETSESFNLELVDIVTKKIYFGQRPEPL +>A0A0D2JS23.1/26-146 +LLHTPSGLAIVEIQGTIHGSFQDLATEDVTQ-----------SPAVHPIGRLEFPLHKPQEAEGKWMKKVYLYVGRHQRLTGEVKKLAKPLAVLRKVDENEL-------------GSESESGEALEIVDVVKFKLMFGARPEPV +>A0A091MRT9.1/42-101 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKQGGAPQP-------------SPGGPDGHYTVTALIKTKLLFKTRPKPI +>A0A5J9TCQ9.1/40-121 +-----------------------------------------------HIGRLCS----TPSPSSSSKAGYTFTVGYH-ELAGTKVALKKPLLVLRKKKVNGGDQD-------P-PTAAAAADVELEVIGVIRHKILFKDRPK-- +>A0A226BEI8.1/238-286 +-----------------------------------------------------------------------------------------------RRKLEEAKAKEKREGRKKRKEGRKERIRRYAVVGIVRKKVVFALRPEPL +>A0A6J2TD64.1/48-141 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLDKPFAVLEKSKTNEGQQLLANVDAT-LDATKSRQRTEYTVRAICTKKLIFKSRPKPI +>A0A4S9NZD5.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGVVEIVEIVRYKVLFGSRPEPV +>A0A453KKJ7.1/112-178 +---------------------------------------------------------------------YTFTVGYH-ELAGSKVTLKKPLLVLRKKKNDNGDTGEL-----GQGGPAAAAEVELEVIGIIRHKILFKDRPK-- +>A0A4T0WW51.1/30-174 +VVSTPTGLTLIEIQGDLSVPQEKPHGLSEREQVFSDGTTNNEPVDVVRFGRLEI---------DESMTKATLFVSSTQRLLGTIEKIDPPLGILKVVHPTGNDNNTDVDQQQQQQQQQQQQQPQCEIVDVVRRKAVNNQRELP- +>F4P674.1/16-141 +---TSNTVILVELQGSIEAQAIVGSDNQV-------------SVSGIHIGEMFI-----------DKDTALLYIGNH-ILDGRKVGLLKPLAILAKVASTQPHGMAISNQNNGPDISRSKQHIFYEAVHLITHKYVFKTRPQ-- +>A0A1W5C9D8.1/39-146 +--------------------------------------------------------------------QPILIIGHH-ILQGRMQKIDKPLLVVEKCDLNRRDDDDEGDEMMLDVSQKVVPKVEYRVRAVVRSKVLFKARPKPI +>A0A6V7Q842.1/91-178 +-----------------------------------------NQLQGLEIGRLCC-SSSSSSQVRFVFVSYTFTVGYH-ELSGSKMALKKPLLVLKKKKAVDGH-----------TSVLNSSEVELQVIGVIRHKILFKNRPK-- +>C8VL51.1/23-146 +LLQTPSGLALLELQGTINLPFQENLDAENES-----TDFNSPSTYETPIGKLMFPDYSQNAKDTSWMKRAYLYVGRYQRMTGEVKKLPKPLAIIQRRQT----------------DGADDAREQLEVVEIVKYKLIFKNRPEPV +>M2TJ52.1/25-160 +ILHTPSGLALLEIQGTIHFPAPITDSEPST-----------------QIGKLVFPHYNPDTNDTKWMKRVYMYIGKGQRMTGECKKLANPIAVLRKRIGEDGGEDGGEDGGEDVDMGEGGKEGELEIVEVVRYRVVFSARPEPI +>A0A341AEG8.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQ----------DCDDLDCRSGTQYVVTALIKNKILFKTRPKPI +>A0A093FBA1.1/3-57 +-------------------------------------------------------------------------------LYGKVVQLEKPFAVLVKRGAGEPG----------PEPGPTGPHASYAVTALIKTKLLFKTRPKPI +>A0A1A9Z3I2.1/837-932 +----------------------------------------------------------------NKYGQPILIIGHH-ILQGREQKLDKPFAVLEKSITNDGQHLLTQSQDTNI--SKSKQRTEYTVRAVCTKKLIFKSRPKPI +>A0A6G1KGV4.1/392-499 +LLHTPSGLALIELQGTIHFPPPSTSSS------------------TTRIGKLVFPLYDPDSADTKWMKRVYFYIGENQRMTGECKKLAKPVAVVRKRLVGEDG-------DVDMEGAEGAGGEELEIVEI-------------- +>A0A0C9Y864.1/27-141 +------EIVLIELQGTLEVESNHPKERNGKL-----------------VGTLKI---------DEITDKPTLLIGHH-LLEGKIVSLPKPLAILHRSSVRSSVDIDSEDDVM----DEEQRSPAWSVVGVVKKKIIFSKRPMPV +>A0A3M7H7H9.1/24-149 +LLQTPSGLAIAEIQGTVNSSLSPEQHTADGA---------------LPLGKLMFPLYDPRMTDTSWHKRVYLYIGKHQRLTGEVKKLLRPIAVLRRKSPADASEER-----ATAGGSGGSGDDDLEVAEIVYYKLLFAHRPEPV +>A0A218Z9K0.1/24-153 +LLQTPSGLAVLEMQGTINLPSHDDQCSISTE------SQSGKIMKETPIGRLSFPGYDPENPNMAWMKRVYLYVGKHQRLTGEIKKLPKALAVIRKRSSKEQDTM---------GPNREEGTEELEVVEIVKYKILFSIRPEPV +>A0A162K2J5.1/24-144 +LIQTPSGLALLELQGAINLPQGKDGAPLPG----------------LQIGRVEFPDHDPAAPDTAWMKRVHMFVGQHQRLTGEVKKLPRAMAVVRRRENRMEYGSGG---------AHMEEGENLEVVEIIKYKLMFGNRPEPV +>A0A2K5LNU9.1/50-113 +---------------------------------------------------------------------PVLIVGHH-ILYGKIIHLEKPFAVLVKHTPGDQD----------CDELGREIGTRYLVTALIKDKILFKTRPKPI +>A0A6D2L552.1/28-113 +-----------------------------------TQSSFQGSLQNLEIGRLCH--------TNSSQETYTFTVGYH-ELIGSKVILKKPLLVLKKL--QKCTD------------DLSGKETELQVVGIIRTKILFKTRPKPL +>A0A5F5XHM6.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQD----------CDELGCKTGTRYLVTALIKNKILFKTRPKPI +>A0A3B4GMD0.1/50-126 +----------------------------------------------------------------------VLIVGHH-IIYGKQVKLEKPFAVLTKHSGHSQGSHSSNNDEITQEAMQGSASTSYSVSALIKTKLIFKIRPKPI +>A0A2G5I6D8.1/46-132 +---------------------------------------QPEIAEALTLGRLVFPPADDDENGPWDGKRVLLYVGDHQRLLGEVKKLAKPVAVVRRST------------------SSGTDDGEVEIAEVVYWKLLFSHRPEPL +>A0A420I203.1/23-166 +VLRIPSGLAILELQGTINIPALNFRAEVENAVEGPKFGLKPGSSKGLSIGRLFFPDYDEKDTETEWMKKVYLYIGSHQKLTGEVVKLSKAIAVIQKKKSDTKDK----------SSMIDETCVQLEIVDIIKYKILFANRPEPV +>A0A540MYV7.1/50-113 +-------------------------------------------------------------------ETYTFTIGYH-ELTGTKLPLKKPLLVLKKTKHSEDGS----------DDDARAAGVELEVIGIIRHRILFKARPM-- +>A0A6P4ZWJ8.1/50-123 +--------------------------------------------------------------------QPILLIGHH-VLHGKVVELEKPFAVLVKEKEKEKKD-DSTDSMDTGESADTVTCSDYLVKAVIRNKLVFKNRPRPI +>G0V6U0.1/24-116 +-IRTPLGTAMLEIQGDLQIEANPQEENA-----------------TVRFGQLQI-----------QDKQATLFIGTKQRLLGQLVALDPPLGLMKFD----------------------KETQKVQLMDFIEWKVLFKDRPLPI +>A0A6A4NPF7.1/50-110 +------------------------------------------------------------------QEVYTFTVGYH-ELTGSKVPLKKPLLVLNKIKNQGGE--------------SGCSKVELRVVGIIRNRILFKTRPK-- +>A0A444TL40.1/17-73 +---------------------------------------------------------------------PVLIIGHH-ILYGKVVEMNKPFIVIRKLV-----------------ESQTENQVDYNVEAVVRKKLIFKTRPKPI +>A0A199VCN2.1/36-116 +-------------------------------------------LQGLEIGRLCC------SSSSSSQVSYTFTVGYH-ELSGSKMALKKPLLVLKKKKAADGDN-----------SVLNSSEVELQVIGVIRHKILFKNRPK-- +>L1JGX1.1/42-122 +-------------------------------------RDSSDSLDGLDIGNLQM---------KKGDKNVSLTVGNQ-RLEGKIVDLSSPLAVMLKRKSEPLQ--------------GGQSATEYSIAGIIKKKIVFNHRPT-- +>E3RQT1.1/25-158 +LLHTPSGLALLEVQGTIHFPTPAPSSSS------------------TQIGKLVFPHYNPDINDTKWMKRVYMYVGKGQRMTGECKKLANPIGIMRKRERKDGGDVEMDDDDDDDEQKNNGGEEELEIVEIVRYKIVFSSRPEPI +>A0A6A5QMU5.1/24-142 +LLHTPSGLAILELQGTFHFPAPTDPLG------------------STQLGKLVFPLYNPALNDTKWMKRVYLYVGKGQRMTGECRKLAKPLGVVRMVKRDGQGD----------VSMEGRQGEEMEIVEVVKWKIVFSSRPEPV +>A0A2J8VVL5.1/3-57 +-------------------------------------------------------------------------------LYGKIIHLEKPFAVLVKHTPGDQD----------CDELGRETGTRYLVTALIKDKILFKTRPKPI +>A0A6A6JZD6.1/27-181 +ILHTPSGLALLELQGTIRFPAPEHGPSTSSPSNPSSSTPLAPSTSSTLVGKLVFPLYNPDVNDTKWMKRVYFYVGENQRLQGEVRRLAKPFAVIRKVEGREGVGEVEGKGDVLMG-DVVEVRDELEIVEIVRFKIVFSSRPEPV +>A0A167QT68.1/34-112 +------------------------------------------EVMDVAIGDITF-----------EKDTALLVIG-HQRLEGKRVGLTKPFAVIKKRTTGFED--------AMETDGGFAAAASYDVVCLIREKYVFSNRP--- +>A0A6U1JSI3.1/143-205 +---------------------------------------------------------------------PFLTIGIH-ELEGEFVTLKKPFVVLDPQQEEDETI---------TTCRGVECRSKFTVAGVIRRKVLFKLRPR-- +>A0A444FWW1.1/26-119 +---------------------------------VESQLATSDQINGLEIGHLCCPS----LSSSSSQPSYTFTVGYH-ELSGTKVQLKKPLLVLKKKAAVDAAGPEF----------SSSSAVELEVIGIIRQKILFKTRPK-- +>A0A3M7EH87.1/24-147 +LLQTPSGLALVEIQGTVNSSLSPEQHTADGA---------------LPLGKLMFPLYDPRMTDTSWHKRVYLYIGKHQRLTGEVKKLLRPIAVLRRKSSADAS-------KERATAGGGSGDDDLEVAEIVYYKLLFAYRPEPV +>A0A182E0M7.1/37-97 +--------------------------------------------------------------DLKWNKKALLHVGHH-ILEGKEVKLQNPLIVLAQD---------------------AENQGTAQIAAVIRKKVQFRTRPMPV +>A0A671RWK6.1/16-132 +------EWLLVELQGEIVSRQNTGLAGNLMG----DLHYTKEFEQNMETYQ-----------MKKNPTNIHLYVGHH-ILYGKQVKLEKPFAVLMKHSGLPRDEEEM-------METNQENPTSYTVSALIKKKLIFKTRPKPI +>A0A1L0B237.1/24-137 +------GDIIVEIQGDLEIDKPNETDRTKTFHIIQICEELQITKDDIDINKLSQLS-QPLKDNSNNKKEVVLFIGTKQRLIGKLLKLPSPLAIMKFDENKNAKI---------------------------------------- +>A0A673Z277.1/52-104 +----------------------------------------------------------------------VLIVGHH-ILYGKVVKLEKPFAVPMET--------------------NHQNPTTYSVAALIKKKLIFKTRPKPI +>A0A3S2PFA6.1/52-118 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLDKPFAVLVKHSGHSQD------SHDEAMETERQDPTSYSVKALIKRKLIFKTRPKPI +>B0DAA1.1/27-141 +------EIVLVELQGTLEVESNHPKERNGKL-----------------VGTLNI---------DEITNKPTLLIGHH-LLEGKIVSLPKPLAILHRSSVRSSVDVDSEDDVMDFEEKEEQRSPAWSVVAVVKKKIIFSKRPMPV +>A0A1E4T3S9.1/14-138 +IISTNLGSTILEIQGELNLPQSKPENLTPEEVPKLLNTTDEVVRDAVRFGRLEL---------EPGFKKATLFISNSQRLVGSVEKVDPPLGVLRIVK------------------DDNNGLEECQVVDVISHKVVFRLRPLPI +>A0A2P4S6T6.1/51-104 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLMKQA-------------------ADPAGTRYAVTALIKTKLLFKTRPKPI +>A0A1T3CDZ8.1/26-144 +LLQTPSGLAILELQGSINLPQGTEGETLK----------------DVEFGRLEFPEYSPDAIGTAWMKRVHMYIGQHQRLTGEVKKLPKALAVVRKRQNRMLES---------SSGPYMEEGDNLEVVDIVKYKLMFANRPEPV +>A0A1B9IQF2.1/63-116 +-------------------------------------------------------------------DKPTLHLGPHHLLHGKFVNLQKPYAVIRKVIGKSNSVEGTTKLEGNASNE--ESNE--------------------- +>A0A0D2WVV9.1/55-147 +------------------------------------------------------------------KGNPNLTIGQQ-MLVGKVTPLKTPIAVMRRKTSTTDAAHSQTSDTPQNN-DAASTSTEYEIAAIVHHKLLFKTRPK-- +>K9G6Q7.1/30-150 +LLQTPSGLALLELQGTINIPSGNEEDDLDYS----TSTDNPASTFETPIGKLMFPDYSVHNPDTRWMKRAYLYVGRYQRMTGEVKKLPRPIAVLQKR--------------------QASEVEELEVVEIVRYKIFFKSRPEPV +>A0A401TAE8.1/4-77 +----------------------------------------------------------------------ILVVGHH-ILYGKVTRLERPFVVLVKQTGVRAGAERPMETETEQEVSEGSILCNYLVTAIIKKKIIFKTRPKPI +>A0A0L1J2D5.1/23-152 +VLQTPTGLAILELQGTINLPSQEAEDESTNP--TNDTHDPSIPTFETPVGKLMFPDYSPHRTDTKWMKRVYLYVGRYQRMTGEVKKLAQPLALVQRRQKEA---------------TSDSDGEELEIVEIIKYKLFFKNRPEPV +>A0A091JH04.1/5-67 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLEKRGAGEPGR----------QPGPAEPDARYAVTALIKTKLLFKTRPKPI +>A0A4Q7K170.1/22-140 +LIQTPSGLALLELQGTINLPHSKDGQPLK----------------DVEIGKIDFPDYVPDAEGSAWMKRVHMYVGQHQRLTGEVKKLPKAIAVIRRRENKVLENSAG---------TYMEEGENLEIVEIVKYKIMFSNRPEPV +>A0A395MZX5.1/22-140 +LLQTPSGLALLELQGTLNLPEDGDGEALS----------------GVDVGRLDFPDYVPDAEGSAWMKRVHLYVGQHQRLTGEIKKLPKAMAVVRKRENKKIVGSGG---------ESEEQGENFEVVEIVKYKLMFGNRPEPV +>D8S2C1.1/47-111 +----------------------------------------------------------------EVCGKFSFTVGYH-ELEGRKMTLKKPLLVLRSSKSQNPR------------VDEAPSSSDLEVVGVVRHKILFKTRPK-- +>A0A0B4IF33.1/22-140 +LIQTPSGLALLELQGTINLPQSKDGQALS----------------GIEIGRIDFPDFVPDAEGSAWMKRVHMYVGQHQRLTGEVKKLPKAIAVISRRENRVLENSAG---------TYLEEGENLEVVEIVKYKIMFSNRPEPV +>A0A158NK03.1/47-110 +---------------------------------------------------------------------PILIIGIH-VLYGKEVILDKPLLVLEKHHDKRDE----------TMEEETTTKTEYFVKAIVRKKLLFKSRPKPI +>A0A3L6RD33.1/50-119 +--------------------------------------------------------------PSSSKGGYTFTVGYH-ELAGTKVTLKKPLLVLRKKKLTGGAADQE---------TPTAAEVELEVIGVIRHKILFKDRPK-- +>A0A0C2CLD7.1/24-66 +----------------------------------------------------------------RDDNEALLLVGHH-LLEGKVSELEKPFLVVRSTPGEDAHSEERT------------------------------------ +>A0A3B3CEM7.1/52-118 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLDKPFAVLMKHSGHSQD------SHDDAMEMDRQDPTSYSVKALIKRKLIFKTRPKPI +>A0A318ZEY2.1/24-155 +LLQTPSGLALLELQGTINIPSHDEASTSAEP---ADSRSQEPSVFETPIGKLMFPDYSPQGPDTTWMRRVYLYVGRYQRITGEVKKLPKPLAIVQRRSTQV-----------PARGSARNDVDELEVVEVVRYKIYFKNRPEPV +>A0A3F2RJF9.1/56-127 +--------------------------------------------------------------------EITLRIGNH-LLTGKVAKLAKPFAILQKNKQHDGDSDVEM---KDTAEDEGDKQVQYEVVGVVKTRVVFASRPKPM +>A0A0C3PL45.1/57-133 +--------------------------------------------------------------NTTDMNKPTLTIGYH-LLEGKVVNLAKPLGVLHKQASAPVG----GESTSSESQEEVGVGTKWDVIAVVKKKMVFSKRPMPI +>A0A0A9N971.1/39-124 +----------------------------------------------LHIGRLCS---APSPSSSSSKAGYTFTVGYH-ELAGTKVTLKKPLLVLRKKKVSAAAAGQEP-------PPSAPAEVELEVIGVIRHKILFKDRPK-- +>A0A1K0G4I8.1/199-244 +--------------------------------------------------------------------------------------------------ETTEGDKDNEDEEQEEDQVEPQTAVYYDVVNVIKRKILFSKRPEPI +>A0A0P1ANR0.1/47-118 +------------------------------------------------------------------NGEITLRIGNH-VLAGKVTKLLKPFAILQKNYSSDDREI-----ELASGNDNGTLQIKYKVVGIARTRVVFASRPKPV +>A0A6A6BGB5.1/24-136 +LLHTPSGLAILEIQGTIHTQPGSTAEQPEQ----------------LPLGKLIFPHYSPEDPNTAWMKRAHLYIGKHQRLTGEVKKLPKPLGVIRRREG-----------------MLDEAPEELEIVDIIKYKIVFSHRPEPV +>A0A1J3FSD7.1/37-118 +---------------------------------------FHGSLQNLEIGRLCH--------TNSSQETYTFTVGYH-ELIGSKVTLKKPLLVLKKL--QQCT------------DYLAGKQTELQVVGIIRTKILFKTRPKPL +>A0A452UXK3.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQD----------CDELGCKTGTRYLVTALIKNKILFKTRPKPI +>A0A2B7WPZ5.1/26-185 +VLQTPSGLAILELQGTINLPDSSAANDSDSLDLESSGFAHSPKQYSTPIGRLIFPDYNEAANDNSWMKRVYLYVGRHQRLTGEVKKLPRPLAAIQRVEESGHKSTAGEMKA-KLQAEECDSCDELEIVDVIKHKIIFSSRPEPV +>Q69TN5.1/25-78 +----------------------------------------------------------------------TFTVGYH-ELAGTKVALKKPLLVLRKKKT-----------------TAVAAETELEVIGVIRHKILFKDRPK-- +>A0A5J9TCL0.1/40-119 +-----------------------------------------------HIGRLCS----TPSPSASSKAGYTFTVGYH-ELAGTKVALKKPLLVLRKKKVGGGD----------KEPPTAAADVELEVIGVIRHKILFKDRPK-- +>W3WKH0.1/25-147 +LIQTPSGLALLELQGTINLPETDPEMEGQAP--------------EIPIGRITFPDYNPNALNTSWMKRVHLYVGQHQRLTGEVKKLPKAMAIIRRRPGSN----------ETTDSAAEDKIEDLEVVEIVKHKLIFSSRPEPV +>A0A1Y2HUE0.1/43-106 +--------------------------------------------------------------NSSDSGNPELIIGNH-RLEGKLVKMSKPFAVLEKTQRAVD---------------VGVDPVEWRVRGIVKYKYMFKTRPQ-- +>A0A482VUU8.1/42-95 +---------------------------------------------------------------------PVLIIGHH-LMFGKEMKMDKPFALLEKK--------------------SDGENTEYIVKSIVTKKILFKTRPKPI +>A0A087GAC9.1/27-110 +----------------------------------ETQSSFQGSLHNLEIGRLCH--------SDSSQETYTFTVGYH-ELIGSKVTLKKPLLVLKKRK-----------------DDLSEKSSELQVLGIIRTKILFKTRPKPL +>B4J1K4.1/16-110 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLDKPFAVLEKSKTNEGEQLLNVTNATLDA-SKSRQRTEYTVRAICTKKLIFKSRPKPI +>A0A091RPH8.1/4-62 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKRGAEEPG--------------PTGPDTCYTITALIKTKLLFKTRPKPI +>A0A0D8YAX9.1/43-104 +----------------------------------------------------------------KDNSEALLLIG-HQLLEGKIIELEKPFLILRPL-----------------SSSQHFEERTMIVDAIIKRKLLFKNRPKPL +>A0A6T6R9B6.1/36-111 +---------------------------------------THATLRNVDLGDLSF----------LPKDKVRLQVGNQ-VLDGEVKRLKKPQAVLSKRR------------------DESSAYTSYDVVGVIRCKLTFTSRPTPL +>A0A3P7LLY9.1/47-139 +------EWMMIEMQGTIENGGKPLSDEVLTTQLRRKTRTVVDHRNHVSVLQPCSTTYIMISSWRREDNEALLLVGHH-LLEGKISELEKPFLVVRTTP---------------------------------------------- +>A0A6T7D881.1/81-127 +-------------------------------------------------------------------------------------------------QNGKEKEREEEREREREREKEKKKECSYEGVGIIKWKYLFKTRPKPV +>Q4E2Z1.1/13-194 +-----QEMLLLELQGKVSIPPKLIREASEKQAEVSDGALGQETVVEVPLGHIDD--------DPRNKKRCSLRIGTL-LVEGSRGQFGEPLLVLRQRKSQPCQQPQHGAQKSPLSSSNEMPTKTYELVGIVERYVHLNSKPL-- +>A0A024U7I7.1/63-125 +--------------------------------------------------------------------VPTLLIGTH-LLEGKVVKLPKPMAIMRKKAKEVSA------------DDTDTTSTAYTVVGIARKKLVFNSRPKPV +>A0A5N5Q2E8.1/29-51 +LLHTPAGLAILELQGTINVPDPD------------------------------------------------------------------------------------------------------------------------- +>B3RVB3.1/55-146 +-----------------------------------QSDGCSESTDPAKVGNIYF----------DDKNTPYIIIGSH-ILDGKVVQIDKPLVVLEKGTLNDQSS------ESDMNHENKNKSVEYSIKGIIKTKLIFKSRPKPI +>A0A4Z1L6M6.1/22-158 +LLQTPSGLALLELQGTINLPEPDIEDDDPSN-----ISNSSEQSFQTPIGRLIFPEYDPANPNTKWMKRVYLYVGKHQRLTGEVKKLPRAYAVIRKRNREISS---HTNGDVSMQNSESEAGDELEIVEIVKWKILFSTRPEPV +>E3TDS5.1/51-116 +----------------------------------------------------------------------ILIVGHH-ILYGKQVKLEKPFAVLMKHSGLPQEDEV-------AMETGQEKPTPYTVSAIIKKKLIFKTRPKPI +>A0A3Q7VPG0.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQD----------CDELGCKTGTRYLVTALIKNKILFKTRPKPI +>A0A6P3XA82.1/48-109 +----------------------------------------------------------------------ILIIGIH-VLHGKQVALEKPLVVLEKH----CNNTGN-------EIMEEKSTTQYIVKAIVKKKLLFRTRPKPI +>A0A6A5UGG9.1/31-157 +LLHTPTGLALLELQGTIHFPTTPSTASAPTS--------------STLVGKLAFPLYNPTVNDERWMKRVYFYVGRGQRMSGEVRKLGRPFAVVRRREEREGDVVMGG-----VDGEERGRGEELEIVEIVKYKVVFSARPEP- +>A0A1E3KDQ0.1/202-251 +----------------------------------------------------------------------------------------------RKRKKLADARRAKKEERKRKRVDGTERTRHYTVVGIVRKKVVFSLRPEPL +>A0A4Y2DWN5.1/85-155 +-----------------------------------------------------------------AKGRPILIIGYH-ILYGKIVENNPPLAILKRSRSSHAL------S-SDPTYNDKVSSTEYTVLALVKKKITFRTRPKPI +>A0A0D2XAN6.1/22-140 +LLQTPSGLALLELQGTINLPQDANGDALG----------------GVQVGRLDFPDFVPGTEGSAWMKRVHLYVGQHQRLTGEIKKLPKAMAVVRKRENKVISGTGG---------ETLEQGENLEVVEIVKYKLMFPNRPEPV +>A0A0C9REY2.1/126-217 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLEKPFAVLEKLKSKDGKSSLNDTNMDSNATLKSRQNTEYVVRALCTKKLIFKSRPKPI +>A0A4Q4W5J5.1/25-150 +LIRTPSGLAILELQGTINLPEADPENEGESE--------------VIPIGRITFPDYNPEFQSTSWMKQVHLYVGQHQRLTGEVKKLPKALAVIRKRAPDGEDV-------DMADSTSETTMDELEVVEIVKYKLVFSHRPEPV +>A0A2J8Q3Y4.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGDQD----------CDELGRETGTRYLVTALIKDKILFKTRPKPI +>A0A6U9Q746.1/46-119 +----------------------------------------------------------------NGKDAPQLYIGHH-MLKGKVEKLKAPFALLRKHKTTEDDVLEEGQTPP---PPPQGPNVHYTIDGIIRRKFIFTTRPT-- +>A0A175WH06.1/395-504 +---------------------------------------VLQNQNPIPIGRLHFPDYHADPQNTAWMKRVYMYVGDHQRLQGEVKKLPRAVAVVRKRGVGKSQVEGEGERER-EGEKGGEGEGELEVVEIVKWKVVFSARPEPV +>A0A6U5BH00.1/56-114 +----------------------------------------------------------------KGDKGVSLTVGNQ-RLDGKVVELGEPLAVMEKRQG------------------EGAAAGEYLVVGWVRRKVVFMHRPT-- +>A0A453KL12.1/77-159 +------------------------------------------------IGRLCS-----TSSAPTSKGGYTFTVGYH-ELAGSKVTLKKPLLVLRKKKNDNGDTGEL-----GQGGPAAAAEVELEVIGIIRHKILFKDRPK-- +>A0A340WSF7.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQD----------CDDLGCRSGTQYVVTALIKNKILFKTRPKPI +>A0A6S8JY85.1/33-132 +------EWALIELNGELIAPPPNLQVDKENPANVSEDSIL--PKSQVELGSVRF-----------VNDQPVMILGPH-ELQGKIETLKHPFCVLRKESS-------------------PSDGTSYRVNGIVTRKILFDK----- +>A0A091GU37.1/31-90 +----------------------------------------------------------------------VLIVGHH-ILYGKVVELEKPFAVLVKQGASPEP-------------DPTGPHACYTVTALIKTKLLFRTRPKPI +>A0A4D5RT65.1/279-340 +----------------------------------------------------------------------VLLVGHH-VLYGKEQKVEKPFLVMRKVMQESA-----------SNGTSKHTAREYHVEGVVTKKLVFRARPKPI +>A0A4C2E5U4.1/24-126 +-VSTPLGNMMLEIQGDLELPRQWSEDQRFTT---------IDKEQLVRWGLLHI--------D-PSRNNAILFVGRKQRLLGSLVKLDTPLGLIKFN----------------------QQDGIVEMQDIFYYKVLFKSRPLPI +>F4W430.1/48-110 +----------------------------------------------------------------------ILIIGIH-VLHGKEVTLDKPLLVLEKHHDTRDE----------RIEEETTTKTEYFVKAIVRKKLLFKSRPKPI +>A0A4U6XM20.1/23-144 +LISTPSGLALLEMQGTINLPHFNPDEDSSKS------------APEVPIGKVVFPDYHPENQSTAWMKRVFLYVGQHQRLHGEVKKLPKAMAIIRRRGEAIIG-------------KGGEVEEELEIAEIVKYKIMFGNRPEPV +>B4N6Q4.2/47-142 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLEKPFAVLEKSKTNEGQR-LLDASQATLDASKSRQRTEYTVRAICSKKLIFKSRPKPI +>A0A1A9VYG6.1/16-107 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLDKPFAVLEKSITNDGQHLLTQSQDTNI--SKSKQRTEYTVRAVCTKKLIFKSRPKPI +>A0A3M6V007.1/47-108 +--------------------------------------------------------------------TPMLIIGHH-LLTGKVVELEKPYAVLYKKTNNED-------------EDNKEGEIHYDVCALVRKKIIFKTRPKPI +>A0A0G4LFF7.1/2806-2896 +-IQTPSGLALLELQGIINLPEDAVDSDGKAT-------------KSIPVGRIDFPDYHPDTQSTAWMKRVYLYVGPHQRLTGEVKKLPKAIAIVRKKDGASN------------------------------------------ +>A0A4Z2EZ71.1/51-123 +---------------------------------------------------------------------PVLIVGHH-ILYGKQLKLEKPLAVLTKH-SSPLDGGEDVTRVDMETNQPGPTSTSYTVAALIKRKLIFKTRPKPI +>A0A642UG83.1/27-174 +-INTPSGVFLVEIQGTVQVGKRPLISGDLELDDDDEGENGAIEENPVPVGAVERQLGYFDFSTTDENNEVTLVIGKHQRLRGKISKMNPPMALIELEKGEEEPQRTTWASQSQRYQPGHDESAELEILEIITHKIVFDSRPEPV +>W2WNN4.1/49-117 +--------------------------------------------------------------------EITLRIGNH-VLAGKVAKLPKPFAILQKDGGTDGDVV------MTEDENDAAGQTKYEVVGIARTRVVFASRPKPV +>A0A1J9Q582.1/26-190 +LLQTPSGLAILELQGTINLPDSSAANDPDTLDLESSGLADSPKQYRTPIGRLIFPDYNDAADDDSWMKRVYLYVGRHQRLTGEVKKLLRPLAAIQRVEETGQECRAGEMKGEKTKARRRDSCDELEIVDVIRHKIIFSSRPEPV +>A0A1B8G5C7.1/25-151 +LLQTPSGLALLEMQGTINTPSPPVQGEDDES--------TQPGSYETPIGRLVFPDYELGTSGGAWQKRVYLYVGMHQRLTGEVKKLPKAIAIIRKRAPSETE----------NTSKEGQGVEELEIVEIVTWKIIFSNRPEPV +>A0A2N5U891.1/64-179 +-----SETIIVELQGALESSSKDLETEDPQA-----------TLEGAEIGLMDI----------SNAEKPILRIGNH-ELEGKFVKLAKPLVVLRRQEIAEKRYPGIDDSEDHGG-RARKTSHRFDIVDIIERKIFFSKRPQPI +>A0A061SIU4.1/50-101 +---------------------------------------------------------------------IHITIGYH-QLDGKVVQLKKPFVLLAKD--------------------HEGQAHKFKVAGIVKQKILFKTRPK-- +>A0A6P7FT28.1/50-102 +----------------------------------------------------------------------LLIIGHH-LLYGKVAKMEKPFALMEKQ--------------------EKDGKTCFVVKAIIRNKIIFKTRPKPI +>A0A668SXG9.1/43-102 +----------------------------------------------------------------------VLIVGHH-IIYGKQVKLEKPFAVLTKHSGHSQD-------------QQGSASTSYSVSALIKTKLIFKIRPKPI +>A0A421JTI5.1/28-151 +IISTSLGLTILEIQGELNLPSHAPNVEITDSEYVENFVKVDDIYDAVKFGRLEI---------DADESKVNLFIGKSQRLIGSIVTLSNPLAVLRVPINNE-------------EEKVDDNINRIRLVDIVXKKMIFKQRPLPI +>A0A6A5ZDS9.1/23-151 +LLRTPSGLAIIELQGTINTPPPSSSSSSST----------------TPVGKLVFPTYKPDVYDTKWMKRVYFYVGENQRMTGEVKKLGKPFAVIRRRERGDADVVMEG--VDVEGEGEGLVGEELEIAEIVRWKIVFAMRPEPV +>A0A5N6ZQH9.1/201-330 +VLQTPTGLAILELQGTINVPSQEAEDESTTS--TNETHDPSIPTFETPVGKLMFPDYSPQRTDTKWMKRVYLYVGRYQRMTGEVKKLAQPLALVQRRQKET---------------TSDSDGEELEIVEIIKYKLFFKNRPEPV +>F7VPJ9.1/25-144 +LIQTPSGLALLELQGTLNIRDFDPSTASPGT------------ISPIPVGRIDFPDYQPNRLDKKWMKRVYMYIGEHQRLHGEVKALPKAVGVVRKRR-----------------HLDDEEKEELEVVEIIRYKLVFASRPEPV +>A0A6J2YRE4.1/49-102 +---------------------------------------------------------------------PLLIIGHH-LMYGKETKLDKPFALLEKC--------------------QEDGNVTYKVRCVVKNKIIFKTRPKPI +>A0A3P8S5C3.1/52-121 +----------------------------------------------------------------------VLIVGHH-ILYGKQIKLEKPFAVLTKHPGHSQDNTAED--VAMETEQQGPASTSYSVSALIKRKLISRRDPNP- +>A0A4Q4X095.1/25-150 +LIRTPSGLAILELQGTINLPEADPESEGKSE--------------EIPIGRITFPDYNPDFQSTSWMKRVHLYVGQHQRLTGEVKKLPKALAVIRKRAPDGED-------VDMADSSSETTMDELEVVEIVKYKLVFSHRPEPV +>A0A1U7V293.1/48-114 +----------------------------------------------------------------SSQENYTFTVGYH-ELTGSKLPLKKPMLVLKKIKLDSKEK----------KCAISSSRVELDVIGIIRQRILFKTRPK-- +>M9LYY2.1/35-212 +------ELVLIELQGELEIDHQHPDGNQ-------------------LLGTMSF--------EPTRPDRPVLMISHH-RLEGKFVSLVRPLAVLEKKIRPDAAQKHVLVDVGNGKRRERQTAVYYDVVSVIRRKILFNKRPEPI +>A0A553QIE7.1/26-88 +----------------------------------------------------------------------VLIVGHH-ILYGKQIKLEKPFAVLVKHSGHPQDV----------EETNEEKPTSYTVSALIKKKLIFKTRPKPI +>A0A093V7E3.1/27-161 +LLQTPSGLAILELQGTINFPATTDDDDDSDMHEEFQAEGAKTKIIETELGKIMFPDYSDLIDSTKWMKRVYLYAGRYQRMTGEVKKLAKPLAVIQRRERSTTE-------------NGNGEQDELEIVEIIKYKIIFASRPEPV +>A0A0B2VDG6.1/48-93 +----------------------------------------------------------------------------NQILQGKAKTLENPLVVIGKG----------------------QQTNENEIVAIIRKKIVFASRPKPI +>S9WZQ1.1/21-103 +-------------------------------------ATVEKVSETFDIGTLEI-------IQENNKKKAAIYVGNQ-CMEGVVETLQKPLAVLQKSHV----------------GNDSLPIQELNIVSFIKEKIRFSSRPLPV +>A0A6U3HUV0.1/22-102 +-------------------------------------------------GKLHFDEVDGTKAVNELQGKATIQTGRY-LIHGDHKKLDRPLAILQKR--------------------PRGKKYTYCVVGVIHQKVVFKSRPCPI +>A0A430LWA9.1/22-139 +LLQTPSGLALLELQGVVNMPQNAEGEPAS-----------------IEIGRIDFPDYIPDAEGSAWMKRVHLYVGQHQRLTGEVKKLPKAMAVVRRRENGTVTGSGG---------ESEEQGDNLEVVEIVKYKLMFSNRPEPV +>A0A428R2A5.1/22-139 +LLQTPSGLALLELQGVVNMPQNSEGEPAS-----------------IEIGRIDFPDYIPDAEGSAWMKRVHLYVGQHQRLTGEVKKLPKAMAVVRRRENGTVTGSGG---------ESEEQGDNLEVVEIVKYKLMFSNRPEPV +>A0A5D2FKD2.1/41-117 +------------------------------------------------IGLLCR---------PSSQENYTFTVGYH-ELTGYKVALKKPMVVLKKIKYMDVERQI-------DEATSSSSCVELDVVGFIRHKILFKTRPT-- +>A0A058Z3M7.1/15-183 +-----LPVAMIELQGKIQNDAEGCAGAVDPCTDGASATCDDDPTSATQSGLVRDVRAGQ--VSKDSMGAYVLTIGRH-RLRGKVAPLKKPLVVLKKGRPGQRGSPANPELDPWT-RSSQAQGVAYSVVAILKEKLVFAARPEPV +>A0A6J1E2M4.1/47-114 +---------------------------------------------------------------PSAQEVFTFTVGYH-ELTGSKVPLKKPLLVLKKKTSVNED----------QSSDSNSTSAELEVIGIIRQRILFKTRPK-- +>N4XGL3.1/25-152 +ILHTPSGLALLEIQGTIHFPAPASSSEPSTQ-----------------IGKLVFPHYNPEINDTKWMKRVYMYIGKGQRMTGECKKLANPIAVLRKRVGEDGGEDVDMGG--TEGEGKRGKEEELEIVEVVRYRVIFSARPEPI +>A0A6J0CZ06.1/32-94 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKRTLGEQD----------CDELGRETGTRYVVTALIRNKILFKTRPKPI +>A0A6V7UH79.1/29-113 +------------------------------------------QVNGQNFGKLLW------EKKDDGKEYVKTIIGRQ-LLQGECVELEKPFIVINRASQRK-E---------KPENASKGDKKSCDVVAIIRRKIYFSGRPKPI +>A0A3B6LLC2.1/77-158 +------------------------------------------------IGRLCS-----TSSAPTSKGGYTFTVGYH-ELAGSKVTLKKPLLVLRKKKNDKGDAGELG------QGGQAAAEVELEVIGIIRHKILFKDRPK-- +>A0A4Q1BW09.1/224-281 +--------------------------------------------------------------------------------------MESPSVLRREREKRKREEEEKKRRKKRKLEHDKERTRYYEVVGLVRKKVVFSLRPEPI +>A0A4S9A283.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKP--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A367KAA7.1/46-100 +-----------------------------------------------------------------NENSAELVIGHH-RLVGKKVKLPKPYAVIHKR--------------------KDSMEASYDVVSFIKEKYVFSQRP--- +>A0A1C7N7X4.1/50-105 +---------------------------------------------------------------------AVLITGHH-RLVGKKAKLPKPLAVIHKRQKEA---------------DSMEEGTSYEVVTILKEKYLFASRP--- +>L7M021.1/56-114 +----------------------------------------------------------------------VLLVGHH-ILYGKEQDVEKPFLVIEKSSGEE--------------GETRVTTKEYLVRGVVTKKVIFRSRPKPI +>A0A1U8KIT7.1/47-111 +---------------------------------------------------------------PSSQENYTFTVGYH-ELTGSKVALKKPMVVLKKIKYMDVA-------------TSSSSCVELDVVGVIRHKILFKTRPT-- +>A0A0A1SVH2.1/23-134 +LLQTPSGLAILELQGTINLPSDAEGAPLP----------------DIEIGRLHFPDYIPDAEGSAWMKRAHLYVGQHQRLTGEVKKLPRALAVVRRRDKT----------------DDQDDTEQLEVVEVVKYKLQFSNRPEPV +>A0A2R9J1A9.1/66-135 +---------------------------------------------------------------PSSKGGYTFTIGYH-ELAGSKVTLKKPLLVLRKKKNGKGGTGEL--------GQGGPAEVELEVIGIIRHKILFKDRPK-- +>A0A6A6D3M1.1/25-143 +LLQTPSGLAILELQGSVLAEHGDVEGSTA----------------VLPLGKLVFPSADGQDGGDWDGKRVFLFVGKHQRMTGEVKKLAKPLAIVRRRRPDVSAD---------DDDAPPAAGDEVEIAEIAHFKILFTHRPEPM +>A0A0A0AVI0.1/42-100 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKRGAGEP--------------GPAGPHTHYTVTALIKTKLLFKTRPKPI +>A0A498JJF5.1/47-113 +----------------------------------------------------------------SSPETYTFTIGYH-ELTGTKLPLKKPLLVLKKTKHSEDGS----------DNDARAAGVELEVIGIIRHRILFKARPM-- +>A0A023FA17.1/50-107 +----------------------------------------------------------------------ILIIGHH-ILYGKCVTMDKPYAVIQKVGDE---------------NTSGGKGTQYLVKALVKQKLLFKIRPKPI +>A0A0D0DB65.1/56-137 +-------------------------------------------------------------MNTADMNKPTLLIGHH-LLEGKVVNLPKPLGVLHKDVHGVVSPDRHPSDANAGPNSAESEQVSWNVVAVVKKKLVFSKRPMPV +>F5A6C0.1/50-119 +----------------------------------------------------------------------VLIIGHH-ILYGKVQDLDKPLAVMRKTRVDE---SMDVDGLQDLQDRHAHQSVEYSIKAIVKKKLLFKTRPKPI +>A0A6P6AJF5.1/36-115 +-------------------------------------------LQNLRIGQLCR---------PSSQENYTFTVGYH-ELTGSKVALKKPMLVLKKIKCMGTDQS---------DEATSSSRVELDVVGIIRHKILFKNRPK-- +>A0A316YUY0.1/67-103 +-----------------------------------------------------------------REDRPTLLISHH-RLEGKIVSLPRPLAVLEKKRRVKED----------------------------------------- +>A0A2V5J8W7.1/238-364 +LLQTPSGLALLELQGTINIPSHDDPSHSAES-------PDGASVFETPIGKLMFPDYSPQNPDAAWMKRVYLYVGRYQRITGEVKKLPKPLALVQRRPTPAGG------------AARGADSDELEVVEVVRYKIYFKNRPEPV +>G4N9V7.1/23-146 +VLHTPTGLALLELQGSINTGEGSASELTAGA--------------ITQVGRLDFPEYVAGKSGGSWMKRVYLYVGTNQRLTGEIKKLPRPVAIIRRRRTGDLDDDE--------VEMQDSGGDELEVVEVVRYKLVFSQRPEPV +>A0A178AL83.1/24-144 +LLHTPSGLAILELQGTFQYPPPAPNTSS------------------TQLGKLVFPHYNPELNDTKWMKRVYMYVGKGQRMTGECKKLGKPLAIVRKRVNENVGAED--------VEMGGVQGEELEIVEVVKYKIVFSSRPEPV +>A0A225AEX5.1/28-171 +LLQTPSGLAILELQGTINVPAASSATESDNAEEPTIRPHSQWKTIETELGKLMFPDYSDLDPNTKWMKRVYLYAGHYQRMTGEVKKLAKPLAIIQRRRKSTTTA-----LAPSEMDQVDATKDELEIVEIVKYKIIFASRPEPV +>W6MU83.1/26-152 +VISTSSGLMILEIQGDLNLPQRIPDKLTETEINTADELGSSGSHTAVKFGKLDI-----------DGKRATLYIGSSQRLVGTIEKIDPPLGLMRIL------------------SESSTEETPIQVLDVIRQKAIFRSRPLPI +>A0A4Z1K1U7.1/22-158 +LLQTPSGLALLELQGTINLPEPDIEDDDPMN-----ISNSSEQSFQTPIGRLIFPEYDPANPNAKWMKRVYLYVGKHQRLTGEVKKLPRAYAVIRKRDREISSQTNGD---VLMQGSESEVGDELEIVEIVKWKILFSTRPEPV +>D7TMR3.1/37-114 +--------------------------------------------QNLEIGQLCR---------PSSQENYTFTVGYH-ELSGSKVPLKKPFVVLKKTRHLDANQNG----------DSKSSSVDLEVVGIIRHRILFKSRPK-- +>A0A6P6WKA3.1/47-128 +---------------------------------------------------------------PSSQESYTFTVGYH-ELTGTKVPLKKPILVLKKTRVSDEDVVEGEGEEEKDS-GPSNSRVQLAVIGIIRHKILFKTRPK-- +>J5JSK5.1/24-144 +LIQTPSGLALLELQGAINLPQGKDGAPLPG----------------LQIGRVEFPDHDPAAPDAAWMKRVHMFVGQHQRLTGEVKKLPRAVAVVRRRENRMEYGSGG---------AHMEEGENLEVVEIIKYKLMFGNRPEPV +>V4RLS3.1/48-114 +----------------------------------------------------------------SSQESYTFTVGYH-ELTGSKVPLKKPLLVLKKVKCMDVDQS----------CEGSSAGTDLEVVGIIRHRILFNTRPQ-- +>A0A2W1BHW1.1/775-846 +------------------------------------------ITEATVVGDLHY---------YNRNKHPVLVLGHH-ILNGKEQKLEQPMAVIEKV--------------------TEGDKTAYKVKAIVKKKLLFKSRPKPI +>T5C2X8.1/26-190 +LLQTPSGLAILEMQGTINLPDPCAANDSDTLDLESSGLADSPKQYRTPIGRLIFPDYNDAADDSSWMKRVYLYVGRHQRLTGEVKKLPRPLAAIQRVEETSQESTAGGMKGRRTKARECDSCDELEIVDVIRHKIIFSSRPEPV +>A0A4Q4ZZ38.1/25-150 +LIRTPSGLAILELQGTINLPEADPESEGKSE--------------QIPIGRITFPDYNPEYQSTSWMKRVYLYVGQHQRLTGEVKKLPKPLAVIRKRAPDGEDV-------DMADSTSETTMDELEVVEIVKYKLVFSHRPEPV +>A0A3B4CJK0.1/51-116 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLEKPFAVLMKHSGLPQDDEVA-------MESSQEKPTAYSVSALIKKKLIFKTRPKPI +>A0A672LBX8.1/51-116 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLEKPFAVLMKHSGLPRDEEE-------TMETNQENPTSYTVSALIKKKLIFKTRPKPI +>F2S325.1/29-168 +LLQTPSGLAILELQGTINLPESDEHAMQDNI----PVVSQHTHKVETPIGRVIFADYDPAADDRGWMKRVYLTVGQHQRLTGEVKKLPKPIAVIQRRKSTVRDAMS--SQSVAQDGYIPATPDQLEIVEIIKYKIMFSSRPEPI +>A0A4S9HRI6.1/48-167 +ILHTPSGLAIIELQGTINFPQANPTEEDCSD-------ANNTITSSTEVGRLVFPLYTPDISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A1R3RUP8.1/219-351 +LLQTPSGLALLELQGTINIPSQDNSDNNQSTSPDGPRDPNAAPVFETPIGKLMFPDYSPQFTDTKWMKRVYLYVGRYQRMTGEVKKLPQPLALVQRRQK----------------ESSAADSEELEIVEVVKYKIFFKSRPEPV +>A0A1E1L400.1/24-157 +LLQTPSGLALLEMQGTINLPSFDDEESISTE------SQSGIASQETPIGRLIFPDYDPAADDAAWMKRVYLYVGKHQRLTGEVKKLPKALAVIRKRNGGEEGEGQV------DNDEDEERVEQLEVVEIVKYKILFSIRPEPV +>A0A061ANA2.1/29-139 +VIATDLGNALLEIQGELILPKEKPTDLTPEE--EEKFSQLQGAEWAVRFGKLEI-----------EGKKATLFIGTTQRLLGDLKKLDPPLALMKIP--------------------DEDSGKQIEIVDVIKYRLVFTGRPLPI +>A0A091FTT3.1/50-108 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKQGATEP--------------DATRADAHYSVTALIKTKLLFKTRPKPI +>A0A7C8YWM8.1/68-135 +---------------------------------------------------------------PSSQETYTFTIGYH-ELTGSRVALKKPLLVLKKVKHSDAD----------SSADSKSSTVELDVVGIIRQKILFKTRPK-- +>A0A074WLE5.1/10-127 +LLHTPSGLAILELQGTINFPTNTASDEDPSS---------DLPSTATEVGRLVFPHYTPGISGGAWMKRVYFYIGKHQRMTGEIKKLAKPLAVLRKA--------------------DGKEEGAVEVVEIVKYKILFGSRPEPV +>A0A6G1L580.1/24-143 +LLQTPSGLAIVEIQGTINSTTTPPPPPQAVM-------QNGMLDGSLHVGKLMFPLYDPSNGDTAWHKRVYLYVGRHQRVTGEVKKLAKPLAVVRRK-------------------EGTRESEELEVAEIIFYKILFAHRPEPV +>A0A3Q3QU36.1/63-144 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLEKPFAVLTKHSGQSQDTVGGHDSNSNGDDARGSTSSSYSVSALIKRKLIFKTRPKPI +>A0A4U5QAG7.1/18-123 +--------VVVELQGTVELNPSFFQTHLQ----------------NLQIGQLCR-------LSSSSQESYTFTVGYH-ELTGSKVTLKKPLLVLKKVKRFMDVDQ----SDDNNKGDLPSSKVELDVIGIIRHKILFKTRPK-- +>A0A4V4KFN0.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A0A1PA40.1/46-100 +-----------------------------------------------------------------NENSAELVIGHH-RLVGRKVKLSKPYAVIHKR--------------------KDSMEASYDVVSIIKEKYVFSQRP--- +>B2W772.1/25-154 +LLHTPSGLALLEIQGTIHFPTPAPSTTS------------------TQIGKLVFPYYNPDINDTKWMKRVYMYVGKGQRMTGECKKLVNPIGVMRKRERKDGGDVEMGLEDDDKEKRNNGGEEELEIVEVVRYKIIFSSRPEPI +>A0A669DH54.1/52-128 +----------------------------------------------------------------------VLIVGHH-IIYGKQVKLEKPFAVLTKHSGHSQGSHNSNNDDITQEAMQGSASTSYSVSALIKTKLIFKIRPKPI +>S7Q262.1/55-113 +------------------------------------------------------------------GDKPTLLIGHH-LLEGKLVTLQKPLAVLHRA------------------QPNEDDGTSYDMIGLVRRKIVFAKRPMPV +>A0A6P7Y6C4.1/51-115 +----------------------------------------------------------------------VLIIGHH-ILYGKIVCLEKPFAVLTKSNTESDGSAM--------ETGEGTPSTCYQLTALIKKKIIFKTRPKPI +>V9EVW6.1/49-117 +--------------------------------------------------------------------EITLRIGNH-VLAGKVAKLPKPFAILQKDGSTDGDVVM------TEDENDAAGQTKYEVVGIARTRVVFASRPKPV +>A0A2T2NU89.1/23-147 +LLHTPSGLAIVELQGIINSPPPAADTA------------------ATTVGKLVFPLYNPDLNDTKWMKRVYFYVGKNQRMAGEVKKLGKPYAVIRKRQKEVGEDVSM----GGVDEEVGAEGEELEIVELVRYKILFSARPEPV +>A0A6U1A8R2.1/31-164 +---TPQEWSLLELNGELIPPPGGTSTVANTT--------SGTGGTRMELGSVRF----------TSDGTPMMTLGSH-ELKGRVEDLKQPFVVMKKKRKRDGDSSGGGGGDDGGGDCLSGAAVSYEVAGVVKKKMMFDNYPK-- +>A0A0N5D7M1.1/41-97 +-----------------------------------------------------------------NNNKALLHIGHH-IMEGKEVKLENPFLVLVRN---------------------TEERTNVQVAAIIRKKVQFRNRPIPI +>A0A673U8F4.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTSGEQD----------CDELGCKTGTQYLVTALIKNKILFKTRPKPI +>A0A0C9Z4R8.1/57-133 +--------------------------------------------------------------NTTDMNKPTLTIGYH-LLEGKVVNLTKPLGVLHKQVCTPV----EGVSTSSGGQEAVGTGTKWDVIAVVKKKLVFSKRPMPV +>A0A507QKH6.1/28-175 +LLQTPSGLAILELQGTINIPSSVQEPVKSDM---SRLPFSQGVTFETHVGKLMFPDYSPHHDDKKWMKRVYLYVGRYQRMTGEVKELSNPVAVIQKRPRRDIGKGNGKGEGEMDVDSVEGDELELEIVEIIRYKLLFKT----- +>G0RY41.1/29-155 +LIRTPSGLALLELQGTINLPGEQQPPQQDCQ---------PQEQDHVPIGRIHFPDYNPNNPEGLWMKRVWLYVGKHQRLLGEVKKMPRAMAVVRKRKKEDGNMGQ----------KGEEEAEELEVLEIVKYKLVFSQRPEPV +>A0A6U3G838.1/55-108 +--------------------------------------------------------------------KPHIKIGNY-LLQGKVVKLPKPMVVLNRLN-------------------KAPNRNEIDIVATIREKYIFSKRPT-- +>A0A0B0N4U4.1/41-117 +------------------------------------------------IGLLCR---------PSSQENYTFTVGYH-ELTGYKVALKKPMVVLKKIKYMDVERQI-------DEATSSSSCVELDVVGFIRHKILFKTRPT-- +>F8PY43.1/60-149 +---------------------------------------------------------------MDDSNKPTLVIGHH-LLEGKVVNLVKPLGVLHRKDRNGNSDQPSSHIQSHDYDQSQKEPAGWDVVAVVKKKIVFSKRPMPI +>A0A0H5BZL8.1/20-132 +VITTSLGNMILEIQGELILPVEKPEVGFIDD-ESKYSKLLSAEQWAVKFGRLEL-----------SGKKATLFIGTSQRLLGDVKTLDPPLALLKFP-------------------SEPETDEPVEVVDVIKHKIIFTGRPLPI +>R7SV98.1/61-137 +-------------------------------------------------------------------TKPTLVIGHH-LLEGKMVSLNKPLAVLHRHDARASHDGADDASMDVDGPLKGGEAKSWDMIAIVKRKMVFSKRPMPI +>A0A0J0XQG8.1/200-249 +----------------------------------------------------------------------------------------------RAREEERAAREREERHRARRRAARPERTRHYEVVGVVRKKIVFALRPEPL +>A0A4Z0ABV8.1/68-189 +-----SELALIELQGSLEVEGDKRGQTVGKL----------TIDADGKVCLLTV-SYPPKLTHAPLKGKPTLLIGYH-LLEGKIVNLSKPLAVLHRTAPPSADADA------MDVDSDAPASPSYEIRAIVRKKLVFSKRPMPM +>A0A6U2ZED8.1/26-152 +-------------------------------------------------GHIEFNGENLKNEFFDSQGHPTLQIGNH-HLQGKKVPLKNPFLVLESSLPGDSS-PSSTKNSSPLSRKLSDVDSKWMGVALIRSKYLFKNRPKPV +>A0A1L9UH65.1/220-354 +LLQTPSGLALLELQGTINVPSQDNAGRNESSSPDSLGNPNGAPVFETPIGKLMFPDYSPQFTDTKWMKRVYLYVGRYQRMTGEVKKLPQPLAIVQRRQKEPSA--------------AADDKEELEIVEIVKYKIYFKNRPEPV +>A0A1X7VWE1.1/52-105 +----------------------------------------------------------------------QLIVGHH-LLTGKVVSLDKPLAVMKKV-------------------KGDGSTKEYNIIAVIKRKIIFRNRPKPI +>A0A6I8TIT7.1/49-154 +--------------------------------------------------------------------QPILIIGHH-ILQGRLQKVDKPLLVMEKCETRKRHITEPSNEEDDAENEKTVPKTEYLVRAVVKHKILFKARPKPI +>A0A5J4X574.1/34-118 +----------------------------------------DKSEESIEIGQLSF-----------LDNEVSLKIENN-ILTGKIENLVKPFLVIEKNKTNNERSEK----ENQNDEKLSKFISEYDIVGVIRRKINFFTRP--- +>A0A1L9X6Q7.1/24-152 +LLQTPSGLALLELQGTINIPASQDERSHSAE------TPDGASVFETPIGKLMFPDYSPQNPDAAWMKRVYLYVGRYQRITGEVKKLPKPLALVQRRPTPA-----------PACSAGGHESDELEVVEVVRYKIYFKNRPEPV +>A0A5N6WVV6.1/226-355 +VLQTPTGLAILELQGTINLPSQEAEDESTTS--TNDTHDPSIPTFETPVGKLMFPDYSPHRTDTKWMKRVYLYVGRYQRMTGEVKKLAQPLALVQRRQKEM---------------TSDSDGEELEIVEIIKYKLFFKNRPEPV +>A0A5C2SXD4.1/58-139 +----------------------------------------------------------------PNTKKPTMMIGHH-LLEGKLVNLAKPLAVLQKHDSTPGAGEEDEAAMAVEDGYTTMQARSWDIIAMVKKKMVFSKRPMPV +>A0A2P6VDS3.1/478-542 +------------------------------------------------------------------SGVVLLTIGYH-QLEGKRMELKKPFAVLDRAASSGGG------------SGEEAAAVEYKVIGVVREKILFKARPRPL +>A0A6L1B6T2.1/25-132 +--ITPLGMMMLEIQGELELPKDFASLARRDS-PNEGRFSEQDGETLIRFGSLQI-----------DGERATLFVGKKQRLLGKVTKLDVPMGIMHFN----------------------SKDNKVELVDVIKYKVIFKDRPLPI +>A0A6P3V9B3.1/51-114 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPREQDCD---------ELGHETGSTQYLVTALIKDKILFKTRPKPI +>A0A1E3BQJ0.1/24-154 +LLQTPSGLALLELQGTINFPSTEEQQPDEQQADNDAAPTATGTTYETPLGKLMFPDYSPQTTDTSWMKRVYLYVGRYQRMTGEVKKLPQPIAVVQRR----------------------GETDELEILEVVKFKMIFKSRPEPV +>L7IVZ3.1/23-146 +VLHTPTGLALLELQGSINTGEGSASELTAGA--------------ITQVGRLDFPEYVAGKSGGSWMKRVYLYVGTNQRLTGEIKKLPRPVAIIRRRRTGDLDDDE--------VEMQDSGGDELEVVEVVRYKLVFSQRPEPV +>G3JI73.1/24-144 +LIQTPSGLALLELQGNINLPKGADGQPLS----------------DVHIGRITFPDYDPAAASTAWMKCVYMFVGQHQRLTGEVRKLPRAVAVVRRRENRLEYGSGG---------AHMEEGENLEVVEIIKYKLIFSNRPEPV +>A0A091CRM6.1/51-114 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLIKHTPGEQDCD---------ELGHEPGTTQYLVTALIKDKILFKTRPKPI +>A0A4U1FNW4.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQ----------DCDDLDCRSGTQYVVTALIKNKILFKTRPKPI +>A0A5C3M4J5.1/58-142 +---------------------------------------------------------------EEGSNKPTLRIGHH-LLEGKISALAKPLAILHRSVPGDPVSKEAPSDNAMEC-DKDGSRAGWNIVGVVKKKIVFAKRPMPI +>A0A2K0UJ11.1/26-144 +LLQTPSGLAILELQGSINLPQDTEGDTLK----------------DVEFGRLEFPEYSPDAIGTAWMKRVHMYIGQHQRLTGEVKKLPKALAVVRKRQNRVLES---------SSGPYMEEGDSLEVVDIVKYKLMFANRPEPV +>I1QMS1.1/25-78 +----------------------------------------------------------------------TFTVGYH-ELAGTKVALKKPLLVLRKKKT-----------------TAVAAETELEVIGVIRHKILFKDRPK-- +>X0DP64.1/22-140 +LLQTPSGLALLELQGTINLPQDANGDALG----------------GVQVGRLDFPDFVPGTEGSAWMKRVHLYVGQHQRLTGEIKKLPKAMAVVRKRENKVISGTGG---------ETLEQGENLEVVEIVKYKLMFPNRPEPV +>B7FXE1.1/29-128 +------EWAVLELNGELIRPKESPDGKENPT------SDCLVGPGQVELGSVQF-----------VDADPVMVMGSH-RLKGKVETLKQPFCVLRKD------------------VDSDNDTTSYQVTGIITKKLLFNQYPK-- +>A0A164TKM4.1/63-134 +------------------------------------------------------------------DDKTTMRIGHH-LLEGKIASLAKPIAVLRKTETKASNPAAHE-----AGLDVPVSEPSFDIVSIAKRKIVFSKRPVPI +>B9WH13.1/28-161 +LIFTPYGLMLLEIQGELNLPIEFPQGQPKTDEYLNNFITINEIHHAVKFGNLVF--------DEKDNSKVTLYVGKSQRLLGNVVKLSTPLAVLKIPLKNEDEM-----MIDNDDNANQQEEELIKLMDIVKAKVIFKQRPLPI +>A0A5N7AY45.1/23-151 +VLQTPTGLAILELQGTINLPSEEAEARSMVS--ANDIHDPSIPTFETPVGRLMFPDYSPQTADTKWMKRVYLYVGRYQRMTGEVKKLVQPLALVQRRQKET---------------NSDSDDEELEVVEVIKYKLFFKNRPEPV +>C3ZBB4.1/38-112 +--------------------------------------------------------------------QPILLIGHH-VLHGKVVELEKPFAVLVKEKEKDNKDDSTESMDTSVSAADTEKCSDYLVKAVIRNKLVFKNRPRPI +>A0A4P9ZR95.1/115-169 +---------------------------------------------------------------------ARLTVGQH-RLQGKIEKLAKPLAYVEAN-----------------PSSNDGSNTTYTINQIIYYKVIFKERPH-- +>A0A6P5Y6R1.1/48-115 +----------------------------------------------------------------SFQENYTFTVGYH-ELTGSKVALKKPMLVLKKIKRMNVDQS---------DEATSSSKVELDVVGVIRQKILFKTRPK-- +>A0A2I2GQ35.1/225-352 +LLQTPSGLAILELQGTINVPSQDGQDDESDPGAGSDSIDPNTPAFETPIGKLMFPDYSPQTTDTKWMKRVYLYVGRYQRMTGEVKKLPQPLAVVQKR--------------------PNTDSEELEIVEIVKFKLLFKNRPEPV +>A0A2H3IDY3.1/27-169 +LLQTPSGLAILELQGTINFPTTTPDDDNNDTDPGAEETNTKKKIIETELGKIMFPDYSEFMDSTKWMKRVYLYAGRYQRMTGEVKKLAKPLAVVRRRERSTMEGN----------RAGEEEGDELEIVEVIKYKIIFASRPEPV +>A0A3Q2Y2U3.1/52-127 +----------------------------------------------------------------------VLIVGHH-ILYGKLVKLEKPFAVLTKHPAQSQGVLGSTGNHDASQVAELHGSTSYSVSALIKRKLIFKTRPKPI +>A9T1E5.1/47-117 +--------------------------------------------------------------------TYKLVIGYH-ELEGTKVTLKKPLVILKKVKAPDAMDTDPV--SSSDPSLSTSTPVEMHVVGIIRHKLLFKSRPK-- +>A0A1E2Y382.1/25-187 +LLQTPSGLAILELQGTINLPVSPAAIDPDVLDLASGGHSQWPTQYETPIGRLIFPDYNDSMDDQSWMKRVYLYVGRHQRLTGEVKKLQRPLAAIQRSEEGGDDVQTRSKAKSNV--NDEDSCDELEIIDIVKYKIIFSSRPEPV +>A0A182QX29.1/864-971 +--------------------------------------------------------------------QPILIIGHH-ILQGRQQKIDKPLLVVEKCELNRPDGEEDVTMLDIS--QKVVPKVEYRVRAVVRNKILFKARPKPI +>A0A445CZA6.1/51-118 +---------------------------------------------------------------PSSQEVYTLTIGYH-ELTGSKVPLKKPMMVLKKVKHSPLDRG----------ESSGCGEIELQVVGIIRHRILFKNRPK-- +>A0A0D1Z471.1/26-146 +LLHTPSGLAIVEIQGTIHGPFQNLATENADQ-----------SQAVHSIGRLEFPLYNPQDAEGKWMKKVYMYVGRHQRLTGEVKKLAKPLAVLRKIDENDH-------------MGDEQSGEALEIVDVVKFKLLFSARPEPV +>A0A0B4HF66.1/22-140 +LIQTPSGLALLELQGTINLPQSKDGQALS----------------GIEIGRIDFPDFIPDAEGSAWMKRVHMYVGQHQRLTGEVKKLPKAIAVISRRENRVLENSAG---------TYLEEGENLEVVEIVKYKIMFSNRPEPV +>A0A5C3P112.1/59-137 +----------------------------------------------------------------PNTKKPTMMIGHH-LLEGKLVNLAKPLAVLHKHGSPPGADDGAAMEVEDGSSRPAAHATSWDVVAVVKKKMVFAKRPLPV +>A0A0N5B9C2.1/45-106 +------------------------------------------------------------------GNSVVMVTGHT-ILEGAVKKLEKPLLLLDKCRYVPN---------------DDSPNSHVKVVGVVKRKISFTSRPRPI +>A0A0P9EJM7.1/30-163 +------EPFLVELQGSLEGPTGEPSAGIEAS-------KAPHLIDGARVGKVDL----------SDPKKPVLRIAHH-RLEGKLETLLTPYALLRTSRAPPPSSDDTA-EPASK--RTTTTTTRIELVALIRRKLVFSKRPEPL +>A0A074Y9C4.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A6J3AQ17.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKRTPGEPGC----------DEFGCESGTRYLVRALIKDKILFKTRPKPI +>A0A4X1VJS3.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGEQD----------CDELGCESGTRYLVTALIKNKILFKTRPKPI +>M2UR08.1/25-152 +ILHTPSGLALLEIQGTIHFPAPASSSEPSTQ-----------------IGKLVFPHYNPEINDTKWMKRVYMYIGKGQRMTGECKKLANPIAVLRKRVGEDGGEDVDMGG--TEGEGKRGKEEELEIVEVVRYRVIFSARPEPI +>A0A1S7HZC7.1/40-142 +-VATPFGNVMLEIQGDLEMPSQWHEDDRFSH---------GEGVDLLRFGLLHI---------NPTNGNATLFVGRKQRLLGSLVKLDTPLGMLKFD----------------------HKSGTVEMQDIFYYKVLFKSRPLPI +>C6HIN8.1/100-264 +LLQTPSGLAMLELQGTINLPDPPTVKDSHTLDLESSGLATSRTQYQTPIGRLIFPDYNDSTDDHSWMKRVYLYVGRHQRLTGEVKKLPRPLAAIQRVDEMDPENGAGGMKKLKQKAKECDSCDELEIVDIIRYKIIFSSRPEPV +>K5XU98.1/53-137 +-------------------------------------------------GELKL--------DETDSRKATLMIGHN-LLEGTIVQLSKPLAILHRSGAEIDSSGVSSKDGDEEEKHVTSNQISWESIGIVKRKVVFAKRP--- +>A0A0D2GPD6.1/26-144 +LLHTPAGLAIMEIQGKIHGPPQDLATEDPEQ-----------SPAVHPIGRLEFPLYNPQEAEGKWMKKVYLYVGRHQRLTGEVKKLAKPMAVLRKVDENDL---------------GSEGEEALEIVDVVKFRLLFSARPEPV +>A0A1U8FDZ0.1/48-114 +----------------------------------------------------------------TSQETYTFTVGYH-ELTGTKVPLKKPMLVLKKIKLDTEEE----------KDNISSSMVELDVIGVIRQRILFKTRPK-- +>A0A674JVD7.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILYGKVVHLEKPFAVLTKRGASEHG----------CDRSPTGAAAHYLVTALIKTKLLFKTRPKPI +>A0A3G2S2B2.1/55-193 +------------------------------------------------IGTLTF--------PPGREDKPILQISHH-RLEGTIVKLRKPLAVLQKRTAPRSRQPASPPTSPTAS-PPLPTTTSYAIVTLIRHKLLFSQRPEPI +>M3JVJ7.1/23-143 +-FFTPYGLTLLEIQGELNLPTEYPKGTPQTNEYLSNFITVDDIHHAVKFGNLVF--------DEKDESKVTLFIGKSQRLLGDIVKLNTPLAVLRVPV-----------------NRHDEGEEDVKLVDIVKAKLIFKQRPLPI +>A0A6V1UCJ2.1/207-268 +----------------------------------------------------------------KDKAEINLTIGYH-RLDGKVMPLKKPIVIMEKSGGG---------------PSDEKQGAQFSVAGVIRSKILFKNRPK-- +>A0A6V0RD85.1/19-149 +--------TLLDIQGSLQVEENPDAPPPPPPGGSAEVDTGGGAAAAVAAGGLRA-DAVRIGELTNTTRNSTLDIGSH-RLVGRTAALARPIGVLKKE-------------------VKSDGSVEWRVVGILREKIVFNTRPKPI +>A0A0J7YMH7.1/3-56 +--------------------------------------------------------------------KATLLIGNH-RLEGKIEELKKPLAVAKFG-------------------ESDDRGRTVEVVGLITRRILFKSRPR-- +>A0A2P5CUE1.1/16-108 +------EWAIVELQGEVEVQPDFQH-----------------QIQSLPIGQLCR---------PSSQETYTFTVGYH-ELTGTKMSLKKPMLVLKKGKK----------------SSDPVGGVDLEVIGVIRNRILFKTRPK-- +>A0A6V7V091.1/6-74 +----------------------------------------------------------------DGKEYVKTIIGRQ-LLQGECVELEKPFIVINRASQRK-E---------KPENASKGDKKSCDVVAIIRRKIYFSGRPKPI +>A0A6J0BM30.1/48-115 +---------------------------------------------------------------------PILIVGHH-ILYGKEVSLDKPFAVLEKIHYNENDQ------VVDKSMSDSRTRTEYTVRAIVKKKLVFRVRPKPI +>M1B9V9.1/40-114 +-----------------------------------------------RIGTLCR---------PTSQENYTFTVGYH-ELTGTKVPLKKPMLVLKKIKLSTEEEK----------GDINSTKVELDVIGVIRQRILFKTRPK-- +>A0A0D2NS64.1/64-139 +-----------------------------------------------------------------AATRPSLLIGNH-LLEGKIAVLPKPYAVLVRNGGPARGSDAD--ADADEDADAMQASAGWTVRGIVKKKIVFSKRPMPV +>A0A0N0V8B1.1/22-140 +LLQTPSGLALLELQGTLNLPEDSNGEALG----------------GVDVGRLDFPDYIPGAEGSAWMKQVHLYVGQHQRLTGEVKKLPKAMAVIQKRENKKIIGSGG---------ESEEQGENFEVVEIVKYKIMFSNRPEPV +>A0A0L0NKV9.1/23-141 +LLHTPSGLALLELQGTVNLPTDANGEILK----------------DVEVGRLEFPDHVSGAEGLAWMKRVHLYIGQHQRLTGEVKKLPRAMAVVRRRENRWYENSAG---------PVQEQGDNLEVVEIVKYKLMFSNRPEPV +>V5BT83.1/13-194 +-----QEMLLLELQGKIGIPPKLVREASEKQAEVSDGALGQETVVEVPLGHIDD--------DPRNKKRCSLRIGTL-LVEGSRGQFGEPLLVLRQRKSQPCQQPQHGARKSPLSSSNEVPTKTYELVGIVERYVHLNSKPL-- +>A0A2J8E5L4.1/24-141 +-IQTPSGLALLELQGIINLPEDAVDSDGKAT-------------KSIPVGRIDFPDYHPDTQSTAWMKRVYLYVGPHQRLTGEVKKLPRAIAIVRKKDGV---------------SNGPDGEEQLEVAEIVKYKLVFSHRPEPV +>F2PSU7.1/29-168 +LLQTPSGLAILELQGTINLPESDEHAMQDNI----PVVSQHTHKVETPIGRVIFADYDPAADDRGWMKRVYLTVGQHQRLTGEVKKLPKPIAVIQRRKSTVRDAMS--SQSVAQDGYIPATPDQLEIVEIIKYKIMFSSRPEPI +>A0A2C9V6M6.1/41-114 +------------------------------------------------IGELCR---------PSSQENYTFTVGYH-ELTGSKVTLKKPLLVLKKVKLMDVDQG----------SENSSVEVALDVIGIIRRKILFKTRPR-- +>A0A6V2Y4B8.1/30-196 +------EWSMVELNGQLMLPASSSGNSDSPN------------DKNMELGSISV----------DDKGCPKMIIGSH-ELEGKFVELKKPLVVMRKRKKLADEIADLSVEYLAD--GQRSKTVEYEVIAILKKKILFDKYPK-- +>A0A1V9YDE7.1/45-102 +--------------------------------------------------------------------VPTLLIGNH-LLEGKITKLVKPMAIMRKEG-----------------SKDDGPGTAYTVVGIARKKLIFNTRPKPV +>A0A226F1E6.1/51-106 +---------------------------------------------------------------------PILIIGHH-ILFGNVQKLEKPFAVLEKVR------------------GSNEAKTEYSVKAVIKRKLCFRERPKPI +>A0A6V1B2R1.1/36-144 +------------------------------------------EGDDMELGSIHF----------ESEANATMIIASH-KLQGKVETLKQPFVVMRPCKRFSSDVIDTSTERDS--SSGQNASNAYEVAGVIHSKILFDKYPK-- +>G3BDT2.1/24-133 +VISTPFGRSLLEIQGVLNVPKEKSAGLEYIT--------VDDIHEAVKFGKLRF--------DEKDKSKVTLLIGNSQRLVGTMANLDTPLGLLKIP----C--------------NEDGSQSQIDMVDIIRKKIIFKHRPLPI +>A0A0F4YJU7.1/26-161 +LLQTPSGLAILELQGTINIPAPTEEELSRAS---DDAAGESGATFETEIGKLMFPDYSPLNPDTKWMKKVYLYAGRYQRMMGEVKKLTKPLAVIRRRQKQHVDGDQS-----LGKRGAGQDGDELEIVEIIKYKILFPSRPEP- +>A0A1L9SA88.1/27-155 +LLQTPSGLAILEIQGTINIPSPDESSDPDEA--IIESSDSSPSVYETPVGKLMFPDYSPQSADTKWMKRVYLYVGRYQRMTGEVKKLGMPLAVIQRRRPEV---------------EAEEGGDELEIVEIVKYKLLFKTRPEPV +>A0A3P8S215.1/52-122 +----------------------------------------------------------------------VLIVGHH-ILYGKQIKLEKPFAVLTKHPGHSQDNTAED--VAMETEQQGPASTSYSVSALIKRKLIFKTRPKPI +>A0A0X8HV52.1/106-131 +----------------------------------------------------------------------------------------------------------------------DESTEKVNLIDIITHKCLFKERPLPI +>A0A0K6FQY1.1/55-112 +-----------------------------------------------------------------DSDKVTLRIGVH-HLEGKIASLPKPLGILTKH--------------------KSDAGTTYEITEIVTKKIIFTKRPTPI +>A0A2N9FMK2.1/51-120 +-------------------------------------------------------------------QVYTFTVGYH-ELTGSKLALKKPLLLLQKIKHSSEADQS----GDTNTQTNSSTNVELQVIGIIRHRILFKTRPK-- +>A0A395NPK6.1/27-145 +LLQTPSGLAILELQGNINLPKDAKGETLK----------------DIEVGRLEFPDYSPDAIGSGWMKRVHMYIGQHQRLTGEVKKLPKAIAIVRKRQNRMLQSSAG---------PYMEQGDNLEVVEIVKYKLMFTSRPEPV +>D4B1C9.1/29-168 +LLQTPSGLAILELQGTINLPESDDHAMQDTI----PDVSQHTRKVETPIGRIIFADYDPAADDRGWMKRVYLTVGQHQRLTGEVKKLPKPIAVIQRRKLTVRDAM--SSQSVAQDGYIPHTPDQLEIVEIIKYKIMFSSRPEPI +>A0A1Y2F1A8.1/31-166 +----NSEPFLIELQGSLELPGRAGVELKEGE------------REGMMVGWVDL-----------EKTKPLLHIAHH-RLEGSIVALPTPYAILRTTPAPVLP-PSKRARLSSPSHADEESKPRIEIVGLVRRKVVFSKRPE-- +>A0A1L9PAI1.1/220-348 +LLQTPSGLALLELQGTINLPNHDDSQFGDES-SNFPSKNDPSLTYETPVGKLMFPDFSPQNADSKWMKRVYLYVGRYQRMTGEVKKLPKPLAIIQRRQPEG----------------SDNSGEQLEIVEVVKYKLMFKNRPEPV +>A0A545W496.1/24-147 +LIQTPSGLALLELQGTINLPQGKDGQPLS----------------DVEIGRIEFPDYDPAGRGTAWMKRVHMFVGQHQRLTGEVKKLPRAIAVVRKRENRMEYGSGG---------AHMEEGENLEVVEIIKYKLMFGSRPEPV +>E4V1H8.1/29-168 +LLQTPSGLAILELQGTINLPENDDRAVQDII----PDASQHTRNVETPIGRIIFADYDPSADDRGWMKRVYLTVGQHQRLTGEVKKLPKPIAVIQRRKVTSPDAMNS--ESVAKDGFIPPSPDQLEIVEIIKYKIMFSSRPEPI +>A0A0C3BQI0.1/54-119 +--------------------------------------------------------------DMSIPAKPTLRIGHH-LLEGKIVSLPKPMAVLKTVPNP---------------EEGASSPIAFDITAIIRKKIVFSKRPSPM +>A0A0U5G0M3.1/24-153 +ILQTPSGLALLELQGTINLPAQDALQPEDEP-TKPPELDTFSATYETPIGKLMFPDYSTQAPDTRWMKRAYLYVGKYQRMTGEVKKLPKPLAIIQRRQKD---------------SGVEDTDEELEIAEIVKYKLIFKNRPEPV +>A0A6P3ZFJ7.1/24-110 +---------------VVEVQPQFQD-----------------RLQNLQIGHLCR---------PSSQEVYTFTVGYH-ELTGTKVPLKKPLLVLKKVKHPS-------------VDAADSARAELEVIGIIRHKILFKTRPM-- +>A0A517LE01.1/25-143 +LLQTPSGLALIELQGTIHVPTSTAEEMDVEN---------AECKTDAPVGELVFPHYSSTNPDTTWMKRVHLYIGQSQRMTGEVKKLPRPIGVMRKK------------------PGFEGGQEELEIVDIVRHKIVFLTRPEPI +>A0A167HEB4.1/56-141 +----------------------------------------------------------------MNEEKPTLRIGHH-MLEGKVVTLPKPLAVLRKRVVPASSQPRIPTPSEESPLQEAAGGTSYEVVEVVRKKVVFSRRPA-- +>A0A1Y2TCK1.1/25-150 +LIQTPSGLALLELQGIINLPETHENGEDNPQ--------------EMSIGRLVFPDYHPDTQSTFWMKRVHLYVGEHQRLTGEVKKLPKAMAIIKKRAKSGEDVD-------MSDGTSSSTTEELEVVEIVKYKLVFSQRPEPV +>A0A553PNV3.1/47-114 +---------------------------------------------------------------YTKAGVPVLIIGHH-ILYGKVQQLDKPLVAMRKVSQNDEH------------MEAYPTQTEYLVQAIIEKKLLFKTRPKPI +>A0A6G1HDV1.1/36-206 +LLHTPSGLAILEIQGTINAPHPQNSPPPPPP------PSSTSTQTQTHVGKLVFPGYFLTSAGEEWMKRVYLYVGKHQRMLGEVKRLEVPLGVLRRRSLAGGEGEGAGAGESEGGVRGEGEGEELEIVEVVRYKILFSGRPEPV +>A0A6V5SJX7.1/46-119 +----------------------------------------------------------------NGKDEPQLYIGHH-MLKGKVEKLKAPFALLRKHKTIEDDVLEEGQTP---PPPPQGPNVHYTIDGIIRRKFIFTTRPT-- +>M5E4Z6.1/64-203 +------------------------------------------------------------------ENQPVLQISHH-RLEGTFVKLRRPLAVMVKQTQAPSPTTPSS--PNPFTSPRRPPMTSYKVVTLVRQKLLFSKRPEPI +>A0A022WC75.1/29-168 +LLQTPSGLAILELQGTINLPESDDQEIQDTI----PDVSQHTRKVETPIGRIIFADYDPAADDRGWMKRVYLTVGQHQRLTGEVKKLPKPIAVIQRRKSTVRDGTSS--QSVAQDGNIPPTPDQLEIVEIIKYKLMFSSRPEPI +>A0A3B4BJP1.1/47-118 +----------------------------------------------------------------------VLIVGHH-ILYGKHVKLEKPFAVLIKHPGHSRDMCD-DTSEAMETELQAPSFTTYSVTALIKKKLIFKTRPKPI +>A0A094F3J7.1/25-151 +LLQTPSGLALLEMQGTINTPSPPTQDEDDES--------NQPGSYETPIGRLVFPDYEPGTSGGAWQKRVYLYVGMHQRLTGEVKKLSKAIAIIRKRAPSETE----------NTSKEGQGVEELEIVEIVKWKIIFSNRPEPV +>A0A0D7AX23.1/61-178 +-----------------------------------------------------------------ALKRPTLRIGNH-HLEGKIVSLVKPLAVLHKTTSPINTDFASSSYTHKPRSKGQARETTWEAVAIVKRKIVFSKRPMPI +>A0A6P6AJA5.1/501-579 +--------------------------------------------QNLRIGQLCR---------PSSQENYTFTVGYH-ELTGSKVALKKPMLVLKKIKCMGTDQS---------DEATSSSRVELDVVGIIRHKILFKNRPK-- +>M9PF23.1/49-131 +---------------------------------------------------------------------------------GREQKLDKPFAVLEKSKTNEGERLLETSMASQDVSMKSRQRTEYTVRAVCTKKLIFKSRPKPI +>A0A0A0KPT4.1/48-114 +----------------------------------------------------------------SAQEVYTFTVGYH-ELTGSKISLKKPLLVLKKTRSVDEDQ----------SSDTKSGNAELEVIGIIRQRILFKTRPK-- +>A0A1E3ICF7.1/200-247 +-----------------------------------------------------------------------------------------------RKKLEEIKQRQK-RTVKKLNGEEKERTRHYAVVGIVRKKVVFALRPEPL +>A0A1X7RFE5.1/24-132 +LLETPSGLAIVELQGSVLSEEQES-----------------DAVQALSLGRLVFPAAEHGENSDWDGKRVFLFIGKHQRMAGEVKKLSKPVAVMRRP------------------ADPTAPQDVVEVTEIVYYKMLFQHRPEPM +>A0A194VBY9.1/411-523 +LLQTPSGLALLELQGTFNTPVPDGSDD------------------TVPIGRLDFPDYKPDSISTAWMKRVYMYVGQHQRLTGEVKKLPKALGVVRRR------------------KGGEMGTDELEIVEIVKHKIVFSSRPEPV +>A0A4T0DNV2.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------TNNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKP--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A3B6MQM8.1/84-150 +---------------------------------------------------------------------YTFTVGYH-ELAGSKVTLKKPLLVLRKKKNDNGDTGEL-----GQGGPAAAAEVELEVIGIIRHKILFKDRPK-- +>A0A6T9ER65.1/50-107 +-------------------------------------------------------------------------VNGPRTLYGSIKKLPKPLVLMQRTESYE-----------PFKGDEARKSLVLKVRGVVRKKAVFTGRPQ-- +>A0A5N6TM45.1/1-75 +----------------------------------------------------MFPDYSPQTPDTKWMKRVYLYVGRYQRMTGEVKKLPQPLALVQRRP------------------NADDSVEELEVVEVIKYKLFFKTRPEPV +>A0A4V4IYV9.1/35-154 +LLHTPSGLAIIELQGTINFPQSASTGEDSSD-------TNNTISSSTEVGRLVFPLYTPGISSGAWMKHVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>S8DFB2.1/47-109 +---------------------------------------------------------------PASQESYTFTIGYH-ELIGTKVSLKKPILVLKRMKKLE---------------TETSSSAELDVIGIIRQKIVFKTRPT-- +>A0A6J0HCH1.1/101-160 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKQGGASQ-------------PSPGEPQGHYTVSALIKTKLLFKTRPKPI +>A0A2T4AQS6.1/26-144 +LLQTPSGLAILELQGSINLPQDTEGETLK----------------DVEFGRLEFPEYSPDAIGTAWMKRVHMYIGQHQRLTGEVKKLPKALAVVRKRQNRMLES---------SSGPYMEEGDNLEVVDIVKYKLMFANRPEPV +>A0A4S4ELC4.1/63-122 +-------------------------------------------------------------------ETYTLTVGYH-ELMGSKVPLKKPFLVLKKLRQ--------------SSSSSSSSREQLEVVGIIRHRFLFKTRPK-- +>A0A1U8KQC1.1/41-117 +------------------------------------------------IGLLCR---------PSSQENYTFTVGYH-ELTGYKVALKKPMVVLKKIKYMDVERQI-------DEATSSSSCVELDVVGFIRHKILFKTRPT-- +>A0A6A5XV45.1/23-140 +LLHTPSGLAILELQGTIHFPTPVPDAQPSTL-----------------VGNIVFPHYKPDADDTKWMKRVYFYIGKNQRMAGECKKLAKPFAVVRKRGTSGGA--GGGEGEDVDMEGGEGGREELEIAEIVRYKI--------- +>A0A5M3MY32.1/56-154 +--------------------------------------------------------------NMDNPDKPTLLIGHH-LLEGKVASLAKPLAVIQRDGDRTNS-PQDASVRGNGTNDKEGATVGWRIVAVVKKKIVFAKRPMPL +>A0A6T2LMG7.1/47-117 +-----------------------------------------------------------------NGKTCTLTIGRH-ALEGNVVQEKGNLVILRKRKREEEPAE-----PQEGAEDSQACPVEYHVVGKIARRFHFKKRPE-- +>A0A151X1I2.1/33-97 +--------------------------------------------------------------------VPILIIGIH-VLHGKEVTLDKPLLVLEKHRDTGDET----------MGEETTTKTEYFVKAIVRKKLLFKSRPKPI +>A0A5N7CD64.1/23-152 +LLQTPSGLAILELQGTINVPSQEFETGSTTP--TSDSHDPSIATFETPVGKLMFPDYSPQTTDTKWMKRVYLYVGRYQRLTGEVKKLSQPIALVQRRQKET---------------TSDLEDEELEIVEIIKYRLFFKNRPEPV +>A0A4Z1GNJ8.1/22-158 +LLQTPSGLALLELQGTINLPEPDIEDDDPSN-----TSNSSKQSFQTPIGRLIFPEYDPSNPNTKWMKRVYLYVGKHQRLTGEVKKLPRAYAVIRKRDREISSQTNV---DVSMQGSESEVGDELEIVEIVKWKILFSTRPEPV +>A0A316V7L4.1/46-199 +----------------------------------------------------------------GREDRPTLLISHH-RLEGKIVSLTKPMAVLEKKQRSATNGEAAPLISLNG--DAGQTATYMEVVCIIRKKLLFSKRPEPV +>J9VTK4.1/206-254 +-----------------------------------------------------------------------------------------------RRKLEEAKAKEKREGRKKRKEGRKERIRRYAVVGIVRKKVVFALRPEPL +>A0A178UJQ2.1/27-111 +----------------------------------ETQASFQGSIQNLEIGRLCH--------SDSSQGTYTFTVGYH-ELVGSKVTLKKPLLVLKKLQFD----------------EVSGKATELEVVGIIRTKILFKTRPKPL +>A0A1B8EV32.1/25-151 +LLQTPSGLALLEMQGTINTPSPSVQDEDDES--------TQPGSYETPIGRLVFPDYELGTSGGAWQKRVYLYVGMHQRLTGEVKKLPKAIAIIRKRAPSEIE----------NTSKEGQGVEELEIVEIVKWKIIFSNRPEPV +>A0A2I2FC99.1/210-342 +LLQTPSGLALLELQGTINLPENEVDFEEPNS------GSGTSTTFETPVGKLMFPDYSPQTTDTKWMKRVYLYVGRYQRMTGEVKKLPNPFAVVQRRQPQAESH--------NARNATDGIFEELEIAEIVKFKIIFKNRPEPV +>A0A066VQS9.1/36-277 +-------LVLIELQGSLEMSGLEDCGEGAQL-----------------LGTLSF--------EKGISEHPVLTVSHH-RLEGKIVSLQKPLAVLEKKRRAGKESAHSGEKEGDQV-QAGPTSTFYEVVSIVRKKIIFSKRPEP- +>A0A1A7MPU9.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGRLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKP--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A4Y7TIL4.1/61-148 +--------------------------------------------------------------------MATLLIGHH-LLEGKVAVIPKPLAIMHRTNSAGRASSTSGTGEMDVEETGEQAPPQWTIQGLVKKKIIFSKRPMPI +>A0A238BPF2.1/45-104 +---------------------------------------------------------------LKWNKKALLHIGHH-IMEGKEVKLQNPLIVLAPE---------------------AENQGIVQITAVIRKKVQFRTRPMPV +>K3VJG8.1/22-140 +LLQTPSGLALLELQGTLNVPEDSNGEALG----------------DVDVGRLDFPDYTPGAEGSAWMKQVHLYVGQHQRLTGEVKKLPKAMAVIRKRENKKIIGSGG---------ESEEQGENFEVVEIVKYKIMFSNRPEPV +>H0GHM2.1/25-132 +--ITPLGMMMLEIQGELELPKDFASLARRDS-PNEGRFSEQDGETLIRFGSLQI-----------DGERATLFVGKKQRLLGKVTKLDVPMGIMHFN----------------------SKDNKVELVDVMKYKVIFKDRPLPI +>A0A699ZVQ8.1/48-105 +-------------------------------------------------------------------DCIQLTIGYH-RIEGKRVSLKKPFAILQRVGSV----------------GESAADVKYEVVGVIRSKFLFKTRPT-- +>A0A2N6NJL6.1/24-144 +LIQTPSGLALLELQGAINLPQGKDGAPLPG----------------LQIGRVEFPDHDPAAADTAWMKRVHMFVGQHQRLTGEVKKLPRAVAVVRRRENRMEYGSGG---------AHMEEGENLEVVEIIKYKLMFGNRPEPL +>A0A5B0N4T0.1/4-79 +------------------------------------------------------------------QEKPILRIGNH-ELEGKCIKLAKPLVVMRRQELAKKKYPGIDESDHSAGG-TRKTSNKFDIVDIIERKLIFSKRPQPI +>A0A2C5WVJ6.1/26-146 +-IQTPSGLAIIELQGTITHTDELSAKLHDEQ----------DVTDTLDIGHITFPNYNPSIHSMAWMKTVYMFVGGHQRLQGEVKKLPQPVAIVRKRRF---------------SNDSPQTEEVLDIVEIIKYKIVFPHRPEPV +>A0A2J8Q3Z1.1/73-135 +----------------------------------------------------------------------VLIVGHH-ILYGKIIHLEKPFAVLVKHTPGDQD----------CDELGRETGTRYLVTALIKDKILFKTRPKPI +>A0A6P7WK94.1/279-340 +----------------------------------------------------------------------VLLVGHH-VLYGKEQKVEKPFLVMRKVMQESA-----------SNGTSKHTAREYHVEGVVTKKLVFRARPKPI +>A0A218WSN4.1/48-116 +-----------------------------------------------------------------SQDTYTFTVGYH-ELTGSKVPLKKPLVVLKKIKHLRMEE-------SSDVNSSSSSEVELEVIGIIRHRILFKTRPK-- +>A0A4W4FAI1.1/51-116 +----------------------------------------------------------------------VLIVGHH-ILYGKLVNLDKPFAVLMKHSGLPQDDEGV-------METSEEKPTSYTVSALIKKKLIFKTRPKPI +>A0A0F8WZA6.1/27-133 +LLRTPSGLALLELQGTINVPSQEIPAIEDEFAVAENTHGPNATTSETPVGKLIFPDYSPQTPDTKWMKRAYLYVGRYQRMTGEVKKLQSLLLSFRSDRNNRDRKQ--------------------------------------- +>A0A5N5FDX7.1/50-113 +-------------------------------------------------------------------ETYTFTIGYH-ELTGTKLPLKKPLLVLKKTKRSEDGS----------DDDACAAGVELEVIGIIRHRILFKTRPM-- +>A0A6J1I4S6.1/52-114 +--------------------------------------------------------------------VYTFTVGYH-ELTGSKVPLKKPLLVLKKKKCVDEDQS----------GDTKSATAELEVIGIIRQRFLFKTRPK-- +>A0A671E8C1.1/51-113 +----------------------------------------------------------------------VLIVGHH-ILFGKIIHLEKPFAVLVKHTPGERD----------CDEPGGKTGTRYLVTALIKNKILFKTRPKPI +>C5GV34.1/26-190 +LLQTPSGLAILEMQGTINLPDPCAANDSDTLDLESSGLADSPKQYRTPIGRLIFPDYNDAADDSSWMKRVYLYVGRHQRLTGEVKKLPRPLAAIQRVEETSQESTAGGMKGRRTKARECDSCDELEIVDVIRHKIIFSSRPEPV +>B5DQ37.2/52-146 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLEKPFAVLEKSKSNEGQRLLDTSIATQDV-SKSRQRTEYTVRAVCTKKLIFKSRPKPI +>A0A3B6KFT5.1/40-124 +-----------------------------------------------HIGRLCS-----TSSAPSSKGGYTFTVGYH-ELAGSKVTLKKPLLVLRKKKNDKGN-PGELG---QGGQAAAAAEVELEVIGIIRHKILFKDRPK-- +>A0A4V3SHJ6.1/23-137 +LLHTPSGLALLEIQGTLNISPDTISASDADS-------------VTTEFGRILFP---SDEERQRGDKRVWMFVGKHQRLLGKCVELKVPMGVLRRKKKEKED-------------GEGAAVEELEVVEIVRWKVVFASRPEPV +>A0A5D2PDL4.1/41-117 +------------------------------------------------IGLLCR---------PSSQENYTFTVGYH-ELTGYKVALKKPMVVLKKIKYMDVERQI-------DEATSSSSCVELDVVGFIRHKILFKTRPT-- +>A0A4Q4TAF3.1/25-150 +LIRTPSGLAILELQGTINLPEADPESEGKSE--------------EIPIGRITFPDYNPEFQSTSWMKQVHLYVGQHQRLTGEVKKLPRALAVIRKRASDGQDVNM-------AGSTSDTTIDELEVVEIVKYKLVFSHRPEPV +>A0A2C6AG26.1/45-138 +-----------------------------------------EPAEDVEIGKLDFPDYVPEAVGSAWMKRVHLYVGEHQRLTGEVKKLPRAVAVVRRRENQWHESSGG---------PVQEQGDNLEVVEIVKYKLVFSNRPEPV +>A0A084WUJ8.1/856-962 +--------------------------------------------------------------------QPILIIGHH-ILQGRMQKIDKPLLVVEKRDIGSSGDGADDETMLDISQMKVVPKVEYRVRAVVRNKVLFKARPKPI +>A0A3N4KU79.1/25-159 +LLQTPSGLALLEIQGTINMPAPSAPLEEEGT--GDNMEIDHSISHETPVGRLVFPDIMNENDNNSKSQRVYLYVGKHQRLTGTLKKLPKPLGVIRRRNPNERETD---------AGDGEWVGEELEIVDIVEWKILFSNRPEPV +>A0A093XQS2.1/25-151 +LLQTPSGLALLEMQGTINTPSPPNQDEDDAT--------SQPGSYETPIGRLVFPDYEPGSSGGEWQKRVYLYVGMHQRLTGEVKKLPKAIAIIRKRAPSETE----------GSSKVGAGAEELEIVEIVKFKIIFSNRPEPV +>A0A2I0BH55.1/81-141 +----------------------------------------------------------------------TFTVGYH-ELSGTKLPLKKPMLVLRKKKAEAEGE----------QGSPDSAGVFLEVVGIIRHRILFSTRPK-- +>A0A0C9MT81.1/46-107 +-----------------------------------------------------------------QDDAAVLVIGHH-RLVGKKVKLPKPFAVIHKRRTD-------------LDIMEEQDGVCYDVVAILKEKYVFPNRP--- +>A0A091HID0.1/16-74 +----------------------------------------------------------------------VLIVGHH-ILYGKVVQLEKPFAVLVKRGAGEA--------------GPEGLPACYTVTALIKTKLLFKTRPKPI +>A0A364MUD1.1/423-551 +LLHTPSGLALLEIQGTIHFPAPNASSPPSTV-----------------VGKLVFPYYNPEINDTKWMKRVYMYIGKGQRMTGECKKLVNPIGIMRKRERRDGGGDVDME-GVEGTMEGAAVKEELEIVELVRYRIVFSARPEPI +>A0A0D2BRX8.1/25-147 +LLQTPTGLAILEMQGTIHGPFPHADETIAEE-------------QTTDIGRLEFPLYNPKEPEGKWMKKVYFYVGKHQRLTGEIKKLAKPLAIIQKVDPETKVDGA---------FTASSTYEDLIVLEVVKYKLLFSGRPEPV +>A0A6S7G8J0.1/33-107 +--------------------------------------------NGLPIGDLHF----------DEKGQPLLIIGHH-LLSGKVVTLEKPFAVLKKLKIVDEE--------------SESTSTEYTVQALVRKKIIFKTRPKPI +>A0A4S8XCM3.1/35-154 +LLHTPSGLAIIELQGTINFPQSNPTEEDSSD-------ANNTITSSTEVGHLVFPLYTPGISSGAWMKRVYFYIGKHQRMTGEIKKLPKPLAVLRKS--------------------QSGEEGAVEIVEIVRYKVLFGSRPEPV +>A0A668S1K6.1/52-128 +----------------------------------------------------------------------VLIVGHH-IIYGKQVKLEKPFAVLTKHSGHSQGSHNSNNDDITQEAMQGSASTSYSVSALIKTKLIFKIRPKPI +>G0WA31.1/27-134 +-IPTPLGHTMLEIQGDLEMPKTVPTDAPDSR----YSKYNDGEIDIVRFGLLNL---------DQEKKLATLFIGTKQRLLGKIVKLDTPLGLLKFD----------------------NSSKKVQLVDVINYKIIFSDRPLPI +>A0A423WAX8.1/42-164 +LLQTPSGLALLELQGTFNTPPPDSDGDGPGG--------------TVPIGRLDFPDYRPDSVSTAWMRRVYMYVGQHQRLTGEVKKLPRALGVVRRREAAAGE------------EEGGGDGDELEIVEIVRHKIVFSSRPEPV +>A8E6W9.1/72-166 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLDKPFAVLEKSKTNEGERLLETSMASQDVSMKSRQRTEYTVRAVCTKKLIFKSRPKPI +>A0A6P7KCW1.1/52-128 +----------------------------------------------------------------------VLIVGHH-ILYGKQVKLEKPFAVLTKHSAHSQGSHISNTQVAMETDQQGPASTSYSVSALIKRKLIFKTRPKPI +>A0A6A6G5S5.1/24-212 +LLQTPTGLAILELQGTIHFPSPPTPSSPPSNSAVVASEATIPERTGTRVGHLEFPLYDLSKGGEAWMKRVYFYVGSHQRMTGEVRRLGRPVAVIRRREQAVVGEGGGEGGAEGTA-GVRGAKEELEIVEIVEYKIVFAARPEPV +>A0A5N5K1S0.1/18-122 +--------VVVELQGTVELNPSCFQTHLQN----------------LQIGQLCR-------LSSSSQESYTFTVGYH-ELTGSRVTLKKPLLVLKKVKGFMDV-----DESDDNKGDLPSSKVELDVIGIIRHKILFKTRPK-- +>V5HI33.1/50-111 +----------------------------------------------------------------------VLLVGHH-VLYGKEREVEKPFLVMRKVTQESAS-----------NGTSKHTVREYHVEGVVTRKLVFRARPKPI +>A0A2K5VYM5.1/49-112 +---------------------------------------------------------------------PVLIVGHH-ILYGKIIHLEKPFAVLVKHTPGNQD----------CDELGREIGTRYLVTALIKDKILFKTRPKPI +>A0A1D9QBD6.1/22-158 +LLQTPSGLALLELQGTINLPEPDFEDYELAR-----HSESSVKSLQTPIGRLIFPEYDSANPNTKWMKRVYLYVGKHQRLTGEVKKLPKAYAVIRKKETRPNSSTNS---DISMQGVESGARDELEIVEIVKWKILFSTRPEPV +>A0A131YUR3.1/56-114 +----------------------------------------------------------------------VLLVGHH-ILYGKEQDVEKPFLVIEKSSGEE--------------GETRGTTREYLVRGVVTKKVIFRSRPKPI +>B4HLV9.1/40-134 +--------------------------------------------------------------------QPILIIGHH-ILQGREQKLDKPFAVLEKSKTNEGERLLETSMASQDVSMKSRQRTEYTVRAVCTKKLIFKSRPKPI +>A0A5N5T9K4.1/50-106 +---------------------------------------------------------------------PVLIIGHH-ILFGKVVEMNKPFIVIRKLV-----------------ESQTENQVDYNVEAVVTKKLIFKTRPKPI diff --git a/tests/data/PF11976_test_filtered_alignment_small.sto b/tests/data/PF11976_test_filtered_alignment_small.sto new file mode 100644 index 00000000..febb2a57 --- /dev/null +++ b/tests/data/PF11976_test_filtered_alignment_small.sto @@ -0,0 +1,1000 @@ +>Query +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A066X8X6|unreviewed|Ubiquitin-like/406-478 +-KIKVLLKTKTDEPLKTSVRPSTTIGTIMELFRKMRGLAADAISLMFDGDELEEDMTVEDADIGDMETIEVYI---- +>A0A817Y9U9|unreviewed|Small/17-93 +EYIKLRVVGQDNSEVHFKVKMTTSMGKLKKSYAERQGVAVNSLRFLFDGKRINDDETPKLLEMEDNDTIDVYQEQVG +>A0A7J7T8X0|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A2U1Q175|unreviewed|Ubiquitin-like/17-92 +-HINLKVKGQDGNEVFFRIKRNTQLKKLMNAYCDRQSVELNSIAFLFDGRRLRGEQTPDELEMEEGDEIDAMLHQTG +>A0A6A5KRE1|unreviewed|Ubiquitin-like/21-96 +EHLNIKVTDNNN-EVFFKIKRTTALGKLMNAFCDRQGKNIQSVRFLFDGRRVTTTHTPDTLDMEDGDTLEVHQEQIG +>A0A392RA87|unreviewed|Rad60/SUMO-like/1-63 +----------DGNAIFVGIDRSTQLKTLVKAYCDHHSVDLNSVTFWFDGNQLQGDHSPAQLHMNDGDEIDAI----- +>A0A8B7KER2|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKIMTAYCERQGLSMRQIRFQFEGQPINETDTTAQLEVEDEDTIDVFQQQTG +>A0A8C2UPL4|unreviewed|Rad60/SUMO-like/49-69 +--------------------------------------------------------TPLQLEMEDEDTIEVFQQQRG +>K2QQB4|unreviewed|Ubiquitin-like/15-90 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMDAFCERQGKSPASVRFLFDGQRVNPTDNPESLEMQDGDTLEVHQEQIG +>A0A0V0GSM0|unreviewed|Small/20-95 +-HINLKVKSQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>S7ZBC1|unreviewed|Ubiquitin-like/360-430 +--MKLMLKSPGLSDFKIKARPSTKVSKIVAAFRQKQNISEGKVHLVFDGDRLEPDQCLSEYDVSDLDMLEVL----- +>A0A8W7PPA5|unreviewed|Ubiquitin-like/14-84 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSLQVVRFRFDGQPINENDTPTTLEMEEGDTIEL------ +>A0A8C0RVC1|unreviewed|NFATC2-interacting/349-400 +---QLRVQGKEKQMLEISLSPDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLTA----------------------- +>A0A9P4NXX5|unreviewed|Rad60/SUMO-like/351-422 +--IRLVLKCKGLENYKLMARPHTPFSKIAGAFRKERSIAAKEISLHFDGEVLDPESTMADSEIEDMDSIEVHI---- +>A0A2I3GQE1|unreviewed|NFATC2-interacting/71-142 +-QLQLRVQGKEKQTLQVSLSQDSPLKTLMSHYEEAMGLSGQKLSFFFDGTKLSGRELPADLGMESGDLIEVW----- +>A0A699HG67|unreviewed|Ubiquitin-like/18-93 +-HMNLKVKSQDGMEVSFRFKRNKKLQTLINEYCDKQSKDITGSVFLLNGEHFSAQKTPDELEMEDGDEIEFMLHMDG +>A0A2U1KBA1|unreviewed|Ubiquitin-like/221-290 +-------KWVGGNEVFFRMRRSTRLKKLMNAYCDRQSVELNSIVFLYEGRRLLGEQTPHELEMEQDDEIYAMPHMTG +>K4G812|unreviewed|Small/15-91 +EHINLKVAGQDGSVVQFKIKKHTPLNKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>H2PNY3|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCEQQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>N1RC56|unreviewed|Ubiquitin-like/416-485 +----IMLKGRDVEPLACKILPETTVETLISYFRQQRNVSDKQVSLWWDGERLEEHVEMKDAEIEAQDTIEVHI---- +>A0A3P6GVP5|unreviewed|Rad60/SUMO-like/51-119 +-KIVITIQDKDG-QKQFRVFADEKFERVFKMYTDKEKLDPQNLVFTFDGDKIDPSTTPSNLEMEDGDMIEL------ +>A0A9P3N626|unreviewed|Rad60/SUMO-like/63-134 +-HVSVRLLSDGGDEQLFKMRRSARLAFLLDLYCQQHRSARASVQLWFHGRPVGELATPDDLRMVDSDSVRVV----- +>A0A7J8U4A1|unreviewed|Small/23-99 +NHINLKVKGQDGNEVFFRIKRSTQMRKLMNAYCDRQSVDLNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A1A8QY52|unreviewed|NFATC2-interacting/174-244 +-EIPLKVRCRAD-VYKIPVLSSTPLTDVVSQLSVILKVPPTSLLLLRHDIELPSDSSVGELGLSIADIIECVV---- +>A0A7L0NS07|unreviewed|Small/12-88 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A9P9QNX2|unreviewed|Ubiquitin-like/87-163 +-EIRICVRTPAAHAIYFKVQPHAKFSSIITAVTDRMKISRKTIRLFHEGHRIKEYDTIASRGVRDGDVLEVFLEQGG +>A0A163IWA0|unreviewed|Uncharacterized/18-93 +EHLNIKVTDNNN-EVFFKIKRTTQLGKLMNAFCDRQGKNISSVRFLFEGTRVGPTDNPDTLDMQDGDTLEVHQEQIG +>A0A3Q1JF10|unreviewed|Rad60/SUMO-like/15-50 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQ----------------------------------------- +>A0A3M6VCH5|unreviewed|Ubiquitin-like/253-313 +-----------KRSEIFKIDSTATVEKLHTSYCKRHAINPDDVVMSVQDQELRLNERLDFYGLMDHDEISV------ +>A0A9P5VTK9|unreviewed|Ubiquitin-like/15-91 +EHINLKVVAQDQSEVFFKIKRSTQLKKLMEAYCERQGKSSNSLRFLYDGERIQPTNTPNDLEMEDGDSIDVMVEQVG +>A0A2K5R6G9|unreviewed|Small/5-70 +-----------FSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMDEEDVIEVYQEQTG +>A0A9P8FFD1|unreviewed|Ubiquitin-like/301-363 +---------QDDREMHCKMTQSMSFKKFIDLYAKRWDIDASAQRLTFNRETVFLSDTPASIGAEHGAVLN------- +>A0A218UVL9|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A428UAB3|unreviewed|Ubiquitin-like/22-97 +EHLNIKVTDNNN-EVFFKIKRTTKLEKLMGAFCERQGKALSSVRFLFDGTRVQPTDTPDALEMQDGDTLEVHQEQVG +>I2GWK2|unreviewed|Ubiquitin-like/18-92 +-HINLKVSDGSS-EIFFKIKRTTPLRRLMEAFAKRQGKDVDSLRFLYDGVRIQPDQTPEDLDMEDNDIIEAHREQIG +>A0A8H5L3N7|unreviewed|Ubiquitin-like/414-483 +----IMLKGRDVEPLACKILPETTVETLISYFRQQRNVGLKQVSLWWDGERLEEHVEMQDAEIEAQDTIEVHI---- +>A0A397HHS6|unreviewed|Ubiquitin-like/332-402 +--IRLVLKCPGFDKFETSVASNRPISQVIAAFRQAKRIPERKIHLVFDGDHLSPSACFADYDITDDDLLDVL----- +>A0A8R2JSG1|unreviewed|MADF/138-173 +EHINLKVLGQDNAVVQFKIKKNTPLKKLMNAYCERT----------------------------------------- +>A0A151NGU2|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8I3MER3|unreviewed|Uncharacterized/16-48 +DHINLKVAGQDGSVVQFKIKRHTPLRKLTKFFF-------------------------------------------- +>A0A8C6GKY3|unreviewed|Ubiquitin-like/16-88 +DHINLKVVGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMSR----SDSGSINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8C5TW27|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A443SHC7|unreviewed|Ubiquitin-like/23-93 +-FVKLRVIDQNNNEVNYRMRKSLQMKKLMDAYSERVGIDRNSLKFYVEHKKIENYDTPATLLLDDDDVIDVL----- +>A0A310SAC9|unreviewed|Small/8-84 +EHINLKVLGQDSAVVQFKIKKHTPLRKLMNAYCDRVGLAIAAVRFRFDGQPINELDTPTTLEMEEGDTIEVYQQQTG +>F8Q389|unreviewed|Ubiquitin-like/15-85 +-----VV-NYEGNHITVKVKANMAFKKIFEAAEKRFGKEPGTFKFVHEGQRLNAMDTPAQREMEDGDMIDAVLEQLG +>A0A087Y2Z3|unreviewed|Small/16-92 +EHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A830I431|unreviewed|Ubiquitin-like/37-113 +DFINLKVKSAQNAEIWFRVKKTTPLNKLMKAYCERNHQDPNSVVFLFDGERIRADQTPSDLDMEDKDEIDAMLHQTG +>A0A3M7DMJ2|unreviewed|Rad60/SUMO-like/383-452 +---VLRAKGVS-QPFKLKVKPTTPFSKIMMACRGHFSVERQQLWLELDGERLDPDEMIQNTDIEDMDNIDVYI---- +>A0A287DEG1|unreviewed|Rad60/SUMO-like/44-61 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A8H6S6E7|unreviewed|Ubiquitin-like/199-275 +---HIRVNCREA-EVSLKVTTATTIRTIFNAVVDKMALGPDNYRMVYDGQRLEEHHTVGSYGMEDGDVLEMWMVQKG +>A0A3D8QQ73|unreviewed|Rad60/SUMO-like/404-476 +-KIRIIIKARNFPDFKTKVSQGTPILKLIVAFKQKHGIEQKDVTLRFDGDALDENANCGDVELEDMDTLEAHV---- +>A0A6C1E4K3|unreviewed|Ubiquitin-like/23-97 +-HINLKVSDGSS-EIFFKIKKTTPLRRLMEAFAKRQGKEMDSLRFLYDGIRIQADQTPEDLDMEDNDIIEAHREQIG +>A0A6J1AXG5|unreviewed|Ubiquitin-like/17-93 +ESIKITVKGQDGSTVVYKIGRKIKLSKLLHSYCQRKQLDYRTVRFVHEGHHVPGQHTADKLKLEDGAEIFCMFLQTG +>A0A022VWB9|unreviewed|Ubiquitin-like/267-318 +---------------------SQNLGEVRKAWCSHQKYDEDTIILTWKGRRLFDVTTCKSLGINDTDTND------- +>A0A1L8EEW5|unreviewed|Small/11-87 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEVYQQQTG +>A0A667X4P1|unreviewed|Small/20-96 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNTLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A8D2AKC0|unreviewed|Rad60/SUMO-like/16-48 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKTYL-------------------------------------------- +>A0A0V0HCB9|unreviewed|Small/20-95 +-HINLKVKSQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A0F7TF87|unreviewed|Ubiquitin-like/335-405 +--MKLLLKSPGLNDFKIKARPKTLVSKVIAAFREKQNIPEKSVHLVFDGDRLEPDTCLGDHDIADLDMLEVL----- +>A0A2C9LXC0|unreviewed|Rad60/SUMO-like/292-361 +EDILVKVRYLSA-VHKFRMNMRRPLQDVINKFAEMKGLDHSSLVFSFDGEEMDPMETPFGLDMESDDCIDV------ +>A0A9N8L379|unreviewed|Small/10-86 +EHINLKVLGQDNAIVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEVYQQQTG +>A0A452J073|unreviewed|Rad60/SUMO-like/130-167 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQVC--------------------------------------- +>A0A6P5LV66|unreviewed|NFATC2-interacting/309-380 +EELRLRVQGQEKQVLEVTVPRGAPLRTLMSHYAEAMGLKGHKLSFFFDGEKLSGQGTPAELGMEQEDLIEV------ +>A0A7L2B794|unreviewed|Small/10-86 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A7R9IK12|unreviewed|Small/14-90 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRVGLAMQTMRFRFDGQPINESDTPVSLEMEEGDTIEVYQQQTG +>A0A3P8VQ36|unreviewed|NFATC2-interacting/69-140 +--IKFRVQSKDRASQEFSLHRDAALGSVLTPYLSCFPCARKKVVFHFDGSKVSLTQTPAELDMEDGDILEVW----- +>A0A2R5LCS8|unreviewed|Small/17-93 +EYIKLKVVGQDGNEIHFRVKMTTQMGKLKKSYSERVAVSVNSLRFLFDGKRINDDETPKQLEMVNDDVIEVYQEQTG +>A0A671YYE1|unreviewed|Rad60/SUMO-like/20-55 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQ----------------------------------------- +>A0A2B4S5P7|unreviewed|Ubiquitin-like/296-367 +-SIEIKVQGKEPSKKTFRILKTDQLEKLMTAYCEYRKLPRSRIKFLFDGEDLKGGETPEQLDMEHEDVIDVQ----- +>A0A437AHJ9|unreviewed|Ubiquitin-like/26-101 +-SINLTIKEQDGPSIKFKTKSNVTFGRILDSFAKETGRSKNDMRLIYKGKIVGHGVTPFDLRLNDDDELEVVASQTG +>A0A6G0VTX1|unreviewed|Ubiquitin-like/4-81 +DCITLNIMGLRNIVFHFTIKKHILFAKLMNAYCEVNGVPFNTVIFNFDGRVINEMDTPTSLDLVNGDTIEVFRRENG +>A0A922L304|unreviewed|Rad60/SUMO-like/104-174 +--LRIIIIDENWSQYCYRIKINTPFGKLINRFCQQVRKDNKSVLFWYHGRCVEDDDTPRTLNIKDNEVILAH----- +>A0A835ZAZ7|unreviewed|Ubiquitin-like/2-57 +---------------------TTKMGKVFTAYASRKGLQVDQLRFMSDGKRIKAEDTPADCGLEDGDQLDCMMEAQG +>A0A8C4KZW8|unreviewed|Small/203-279 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A8C6B1V6|unreviewed|Small/16-92 +DCINLKVAGQDGSTVQFNIKRHAPFSKLMKAYCERQGLSVRQIRSQFDGQPINETDTPAQLEVEDEDATDVFQQQTG +>A0A0S3RUS9|unreviewed|Small/22-97 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFSSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A8J5FFQ2|unreviewed|Rad60/SUMO-like/17-87 +------ISIRDGNHLSMKMSQTTKLGKVMEVFCESKCLPLTSLSSTFDHWKVGEDQTPEQLGMEDGAEMEAHKSAFG +>A0A2Y9G7Z6|unreviewed|Rad60/SUMO-like/54-70 +------------------------------------------------------------LEMQDEDIIDVFQQQTG +>A0A9P8GND8|unreviewed|Ubiquitin-like/303-374 +--ITVKYLGQDDREMRCKMTQTMCFDKFISLYSKRWGIDPPTQHLTFNGKTVFPSDTPVSIGAQDDAVLDVA----- +>D2VIM5|unreviewed|Ubiquitin-like/266-337 +EKITISIRWNDK-TISVNIHERDKFQKLKKTVAKKFEVHPDQISFKFDGATLDLNSTPEDQAMESDDIIDCIV---- +>A0A9L0R522|unreviewed|Rad60/SUMO-like/20-55 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQ----------------------------------------- +>A0A9F2R875|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A292Q3Y8|unreviewed|Rad60/SUMO-like/356-429 +ESIGIVLKSKGYGNFPTKVRPSTKISELIDSFRIARAIDPSAIILDFDGDQLDPDGEIRDTELEDMFTVDVYV---- +>A0A0R3Q021|unreviewed|Small/17-89 +EYIKLKVVGQDSNEVHFRVKNGTAMGKLKKSYADRTGVAVSSLRFLFDGRRINDDDTPKTLEMEEDDVIEVIS---- +>A0A286XR67|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A7K8WIH9|unreviewed|Small/17-93 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A8C9E978|unreviewed|Rad60/SUMO-like/20-64 +EYIKLKVIRQESSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRI-------------------------------- +>A0A6B0REF0|unreviewed|Ubiquitin-like/23-82 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQ----------------- +>A0A6P8QYY0|unreviewed|NFATC2-interacting/171-241 +-EITIKVRRRSS-LFRISLRMFDPLQKLVDQMALKLQVDPGQILLLLRDEELPVSKSPQALKLTVADIIDCVV---- +>A0A1G4GZ33|unreviewed|Ubiquitin-like/20-96 +EHIQVKVRSPDGAEVFFKIKRKTKLEKLMEVYCNRLGQSMEAVRFLYDGDRIHGENTPDQLGIEDGDVIDAMVQQTG +>A0A4S9RUZ6|unreviewed|Rad60/SUMO-like/373-445 +--IKVTLKARGHSDIKIKVRPSTTFMKMINAARRSFKLDPRQLHLEFDGEKLEPEGLVKDTDISDMDCIDVHI---- +>A0A8H6EN27|unreviewed|Ubiquitin-like/401-469 +----LKAQSKDIKEFKTYVKPTTTIKKLVDGFRSTNKIPAKKIILSFDGDHLELDSTVEEAGFDDMDTVDVL----- +>W2TJG6|unreviewed|Ubiquitin-like/262-325 +----------SGRPRCVYLKLTETFADAKKRIEKALQLSSGVERLVFDNDVLDDSDTPTSIDMEAEDVIEIHLK--- +>A0A433PGZ8|unreviewed|Ubiquitin-like/14-90 +DHINLKVVGSDHNEVFFKIKRTTQLKKLMEAYCDRQGKTTNSVRFLYDGIRIQPTNTPNELEMEDGDSIDVMVEQIG +>A0A8C2MDN9|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A7K8V578|unreviewed|Small/10-86 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A5J5PXU1|unreviewed|Rad60/SUMO-like/14-91 +DPIVVKVQGQTQNTLNYWMGRNTPLRFLMLDYCERTGAVFEYTRFHVDGLRISSTKTPHDLEMEDGDIIDANSNQSG +>A0A182PSK3|unreviewed|Small/14-90 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSLQVVRFRFDGQPINENDTPTTLEMEEGDTIEVYQQQTG +>G8BU76|unreviewed|Ubiquitin-like/28-102 +-HINLKVSDGSS-EIFFKIKRTTPLKRLMEAFAKRQGKEMDSLRFLYDGIRLQADQTPEDLDMEDNDIIEAHREQIG +>A0A139Y3G9|unreviewed|Ubiquitin-like/13-89 +EHMQLKVRSPDGSEVYFKIKKKTKLEKLMQAYCNRLGQHMDAVRFLFDGERVKPEKTPLDMGIEDGDVIDAMVQQTG +>A0A8X6UTP8|unreviewed|Small/15-91 +EYIKLKVVGQDSNEIHFRVKMTTQMGKLKKSYSERVGVPVTSLRFLFDGRRINDDETPKQLEMENDDVIEVYQEQTG +>A0A1A6H299|unreviewed|Rad60/SUMO-like/16-54 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQFLH-------------------------------------- +>A0A8S9E6K9|unreviewed|Small/9-85 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDEDTIDVFQQQTG +>A0A5J4TTM3|unreviewed|Rad60/SUMO-like/15-77 +---TIIVRTPTGEEIFFKIRDKTPLKKVIEAYCNS-----------FDGQRIKDIDTPKSLDMQENDVIDALVEFHG +>A0A813QNB6|unreviewed|Small/14-90 +EYIKLKVVGQDNSEVHFKVKLSTNMGKLKKSYSDRQGVPVGSLRFLFDGKRINDDETPKTLEMEDGDVIEVYQEQVG +>A0A1E1IPS9|unreviewed|Ubiquitin-like/35-110 +-QISLKVVNADGAEMFFKIKRGTQLKKLIDAYCKKQGISRGSVRFLFDGAPIDESKTPEDLGMEDDDVIDAMVEQTG +>A0A8H6HNY6|unreviewed|Ubiquitin-like/18-86 +--------GYEGQNVTVKVKANMKFQKIFEVVEKRFQKDSGTFKFVFEGQRITPEDTPGSLGMEDGDQIDAFLMQVG +>A0A059AWC7|unreviewed|Small/23-82 +-HINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVELNSIAFLFDGRRLRGEQTPDEV---------------- +>A0A8S0SY49|unreviewed|Small/2-69 +---------QDGSEVVFRIKRNTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRAEQTPDELEMEEGDEIDAMLHQTG +>Q5ZBN3|unreviewed|Rad60/SUMO-like/162-233 +EKVVVTVQDKAG-HHQFRLYKDEKFGKLFRAYAKKVNLSVADLTFAFDGDKVDAESTPEDLGLEDEDMVEVLH---- +>A0A368RDA4|unreviewed|Ubiquitin-like/43-107 +-------QSQ------IAADRNVKLRRLMDMYCGKHSLDPKAVLFLAEGRHIRPAQTPDDVGLKDGDEIDILLKQDG +>A0AAD5LFI9|unreviewed|Ubiquitin-like/246-316 +---EFKVQSQNRSQVVVSIRAEDPMKILMQKYAEATGCNLAKLTFKFDGELLTDSDTPSNLELEGGECIDVYV---- +>A0A5N5SKG4|unreviewed|Small/6-77 +-----KVVGQDGQIVHFKIKKHTQLKKLINAYCEKSKLVPSTVRFRFDGQPIAESDTPQSLEMEDGDTIEVFQQQTG +>A0A7K5VEB3|unreviewed|Small/11-87 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A671V876|unreviewed|Small/18-94 +EHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTLRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTG +>A0A2T9YHF1|unreviewed|Rad60/SUMO-like/424-494 +DTIKIKIRNKSGVDKHLEIAKTVKVSAIINLYKEMLQLSSNNVSLSFDDERIDVNVAIGDTEIENEDMLT------- +>A0A8C9U062|unreviewed|Small/19-95 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVHVSSLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A182XYC4|unreviewed|Small/28-104 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTTLEMEEGDTIEVYQQQTG +>H0WCS2|unreviewed|Rad60/SUMO-like/16-51 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQ----------------------------------------- +>A0A370BSD9|unreviewed|Ubiquitin-like/12-87 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMDAFCERQGKQPSTVRFLFDGTRVRPEDTPDTLEMADGDTLEVHQEQIG +>A0A2K6PRZ1|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8C9J124|unreviewed|Ubiquitin-like/167-243 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0AAD6FF68|unreviewed|NFATC2-interacting/192-261 +--IPLKIRCMTH-VHKIPVLSSTPLSDVLTRLSVILDAPPPRLMLLRKEEELPANSTVGELGLGIADIIECVS---- +>A0A376B399|unreviewed|Ubiquitin-like/26-100 +-HINLKVSDGSS-EIFFKIKRTTQLKRLMEAFAKRQGKDVSSLKFLYDGVRIMADHTPEDLDMEDNDMIEVYREQLG +>A0AAA9SHC1|unreviewed|Small/2-71 +-------SDQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A3B0K5B4|unreviewed|Ubiquitin-like/251-301 +------------EIQHYKLRQHRKFLHMFKEVAERNGVDVDDIVIDKYDTLVEPTDTPHSIGL-------------- +>A0A7S3LVD5|unreviewed|Rad60/SUMO-like/34-87 +-------AFQNGGNVHFKIKSQTPLKKLFGAYCTRTGVDPASVVFLYEGERVDPEMTPIQV---------------- +>A0A3S3NVW3|unreviewed|Ubiquitin-like/46-122 +EYIKLKVVGQDSNEIHFRVKMTTQMGKLKKSYSERVGVPVTSLRFLFDGRRINDTDTPKQLEMESDDVIEVYQEQSG +>X8J2K0|unreviewed|Ubiquitin-like/119-195 +DKITLVIRSQEGPSFQIKVSRVKSLKGAFDKAHEQFRKAPNTFRFFYNGTRLQDDDTPKMHEMENNDEIDANIQQVG +>A0A6A1Q953|unreviewed|Rad60/SUMO-like/16-52 +DRINLKVVGQDGSVVQLKIKRHTPLSKRMKAYCERQD---------------------------------------- +>A0A4C1TWQ5|unreviewed|Rad60/SUMO-like/337-408 +DLITIKFQSQIRHPLEIKVFLEEKFSVAFMKCAEQLDVGVERLKFYFDGDMINPQSTPRGFEFEDGECIDV------ +>A0A2K3L760|unreviewed|Rad60/SUMO-like/22-91 +--VSLNFKGKIENEYFSNVRRSNQLKNLMDDYCRRYWLDIDGVAFLFNGCLLRAEQTPDELQLVNGDEIDVV----- +>W4JV61|unreviewed|Ubiquitin-like/23-97 +--INVKVVTSQGEEVFFKIKRNTKLSKLQGAYANKVGKDVGSIRFLYDGNRINDDDTPASLDMEDNDTIDVMVEQVG +>C4YCV9|unreviewed|Rad60/SUMO-like/413-484 +-----GLKGKDNKRVEVKVSPETQLRKLLSYYLRHKGLSESKAKLIFDDEEMDLNDTVGDTELEEDYEIQVV----- +>A0A8B9I987|unreviewed|Rad60/SUMO-like/16-51 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQ----------------------------------------- +>A0A2P4QUR9|unreviewed|Ubiquitin-like/28-81 +------------------VLRTTPFKKLKEVYCKRNRLKIHATKFLFDGLNVMDNDTPDSLEMEEGDSIHVI----- +>A0A0M9A768|unreviewed|Small/8-84 +EHINLKVLGQDSAVVQFKIKKHTPLRKLMNAYCDRVGLAIAAVRFRFDGEPINELDTPTTLEMEEGDTIEVYQQQTG +>A0A7L1N6E5|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>Q9USX3|reviewed|DNA/334-405 +--ITLLLRSSKSEDLRLSIPVDFTVKDLIKRYCTEVKISFERIRLEFEGEWLDPNDQVQSTELEDEDQVSVVL---- +>A0A3B3DUC8|unreviewed|Small/3-71 +--------DTDSSEIHFKVKMTTHLKKLKESYSQRQGVAASTLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A9P1DFG3|unreviewed|HMG/210-266 +-------IGEDGNVLDFKMKPRTPFKTALEAWCDHHGIPQDQVLFEFQGAPLLPSKSPAECGW-------------- +>A0A8S1BS30|unreviewed|Ubiquitin-like/327-396 +--LRIKFQCQHKKPFETTIRPDDTFGLAMMKCAEHLETPLNRLKFFFDGDLISSKTTAEELDLEGGECIDV------ +>A0A8X8ZBU3|unreviewed|Rad60/SUMO-like/205-257 +---------------------DDKFERLFKIYADKTKLDVKNLVFCFDGDKVTPDQTPNSLGMEENDILEVHVK--- +>A0A427YAY4|unreviewed|Ubiquitin-like/92-124 +--------------------------------------------LLFDGQRIVDNQTAEDLEMEDGDVIEVLLEQVG +>A0A4Y1R2B7|unreviewed|B/144-214 +-KIVLSIQDKDG-AKQFRIYVDDKFERLFKMYADKAKLDLKSLVFCFDGDKIGPAATPDALGMEDNDIIEVHI---- +>A0A438H520|unreviewed|Ubiquitin-like/58-108 +-------------------------RRLMSAYCGRQSVELNSITFLFDGHRLLGEQTPDELEMKDGDEIDAMMHQT- +>A0A9W9T3I9|unreviewed|Ubiquitin-like/324-395 +-PMKLILRSPGYDDFRIKARKKTLISRLISAFRDKQNISVDDIFLLFDGDKLDPDSCLGDHDIDDLDLVDVQ----- +>A0A1Q3DKC9|unreviewed|Rad60/SUMO-like/144-215 +-KIVISIQDKDE-LKLFRVFVDDKFERFFKMYADKTKLDLQRLVFCFDGDKISPTETPVGLGMDDNDIIEVHVK--- +>A0AAD4RZE8|unreviewed|Rad60/SUMO-like/146-216 +-KIIISIQDKDG-AKQFKVYVDEKFEKFFKQYADKVKREIQSLAFCFDGDKINPAETPASLGMEDDDIIEVYT---- +>A0A7K6MBQ7|unreviewed|Small/17-93 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A1I7RL99|unreviewed|Small/23-99 +EYIKLKVVGQDANEVHFRVKFGTSMGKLKKSYAERTGVQIGSLRFLFDGRRINDEDTPKTLGMEDDDVIEVYQEQVG +>A6I949|unreviewed|NFATC2-interacting/261-329 +---TLKIRCRAD-LVRLPVKTSEPLQNVVDHMASHLGVSPNRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A9D4B7M4|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLNKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8K0DQB9|unreviewed|Rad60/SUMO-like/147-217 +-KIVISIQDKDG-PKQFRVYLDDKFERVFKLYADKAKLDLQNLVFCFDGEKVGPQATPLSLGMEDDDIIEVHS---- +>A0A8K0TA71|unreviewed|Ubiquitin-like/22-97 +EHLNIKVTDNNN-EVFFKIKRSTKLEKLMNAFCDRQGKAPATVRFVFEGQRVQPTDTPDALEMADGDTLEVYQEQVG +>A0A9P5MRT9|unreviewed|Ubiquitin-like/16-84 +--------SHSGTQVTVKVKANMPFKKIFEVAEKRFGKDPGSLRFVYDGERLSPTETPAERSMEDGDVIDALLQQLG +>A0A178FPB0|unreviewed|Ubiquitin-like/14-89 +EHLNIKVTDNNN-EVFFKIKRSTQLKKLMDAFCERQGKQLSTVRFLFDGTRVRPDDSPETLDMQDGDTLEVHQEQIG +>A0A0H5SAE5|unreviewed|Ubiquitin-like/259-322 +----------EQKPVITAVPRDTPFMIVKRDFAVDNGLDEEKLTLIFDGKRISPQETADTLGIEDGDCVDVYM---- +>A0A0P8Y742|unreviewed|Rad60/SUMO-like/3-74 +-RIDLKVRSPNRGQVDFHISVKMPLEKMMRAYADYYKMPYKRFVFRVRGLRIEDTDTAEVLSLRNNDIINVVE---- +>A0A8D2B1R9|unreviewed|Small/19-91 +----LKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A182PQ83|unreviewed|Ubiquitin-like/416-486 +-MITLKVQLEKRQPLRLQIDKNQTMSVLVIKCAEELKCEPKAIRLYFDGDMVDNTSKPADLELEGDEMLDC------ +>A0A5B0PZM3|unreviewed|Rad60/SUMO-like/726-799 +--INLTVRTKDKQKVELSVKPSTSIRSILKNSLIHLNFDPTRFKISFDGEDLPFSSIVSDHDLDHDDVLDL------ +>A0A167SHT0|unreviewed|Ubiquitin-like/26-101 +EHLNIKVTDNNN-EVFFKIKRTTKLEKLMAAFCERQGKSMSSVRFLFDGQRVQLSDTPESLEMQDSDTLEVHQEQLG +>A0A834U181|unreviewed|Ubiquitin-like/227-295 +---QIKVQTANKESLMIPLKKNQQFKILIASCARQWGVNKSNIKLYFDGEAINVSDTPESLDLEQEACIDLC----- +>A0A1L7V2X8|unreviewed|Ubiquitin-like/19-94 +EHLNIKVTDNNN-EVFFKIKRTTKLEKLMGAFCERQGKATSSVRFLFDGTRVQPTDTPDALEMQDGDTLEVHQEQVG +>F8P266|unreviewed|Ubiquitin-like/15-85 +-----VV-NYEGNHITVKVKANMAFKKIFEAAEKRFGKEPGTFKFVHEGQRLNAMDTPAQREMEDGDMIDAVLEQLG +>A0A6J2EPF8|unreviewed|NFATC2-interacting/262-329 +----LKIRCRAD-VVRLPVRVSEPLQRVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A1A8VEN2|unreviewed|Ubiquitin-like/1-61 +----------------FKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTG +>A0A8C9DT35|unreviewed|NFATC2-interacting/345-416 +-QLQLRVQGKEKQMLEVSLSRDSPLKILMSHYEKAMGLSGHKLSFFFDGTKLSGRELPADLGMESGDLIEVW----- +>G4ZG23|unreviewed|Rad60/SUMO-like/209-270 +-----------KRSEIFKIDSTATVEKLHASYCKRHGISPGDVIMSVQDQELRLDERLAFYGLIDLDEISVK----- +>A0A5N5DPE1|unreviewed|Ubiquitin-like/15-90 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMDAFCERQGKSPASVRFLFDGQRVSATDNPDTLEMQDGDTLEVHQEQIG +>A0A3Q1G6L6|unreviewed|NFATC2-interacting/316-387 +--ITVRLQSKDRSSQEFSLDRGSPLGSVFSKYLSTMSANQKKVRFHFDGCKVTNSQTPAQLDMEDGDIIEVW----- +>A0A673XUJ3|unreviewed|Small/10-84 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQTN-- +>B7ZQM3|unreviewed|Small/21-97 +DYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRISDHQTPKELGMEEEDVIEVYQEQTG +>A0A8C6L8G7|unreviewed|Ubiquitin-like/20-56 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQV---------------------------------------- +>A0A7J8N234|unreviewed|Rad60/SUMO-like/131-195 +---------ADGALYYYLIGRNTPMKNLLLDYADRVNELYEQVSLTCRFCRIDMGKTADDLALEDGDVIYAFL---- +>A0A4S9T6E3|unreviewed|Ubiquitin-like/222-296 +---KVEVDGKWVKEMEFVVGPDVKVKDFKDAWAKRAGCSVDSVVFRFTGTKYTEDETFGDLDLQPDDKVYV------ +>A0AA39NMW8|unreviewed|Ubiquitin-like/69-141 +----IIIATSSGEQKTYKLRDDTPLKKMLTSFAVSYGKEMSSFMFVYEGRRINPEQTPRMYDMEDDDVIDAMIEQIG +>A0A4W3H8R7|unreviewed|Rad60/SUMO-like/65-82 +-----------------------------------------------------------QLGMEDEDVIEVYQEQTG +>A0A3Q1B5E0|unreviewed|Rad60/SUMO-like/52-84 +------------------------------------------VRFHFDGCKVTNSQTPAQLDMEDGDIIEVSLKQ-- +>A0AAD3XRG6|unreviewed|Small/20-95 +-HINLKVKGQDGNEVFFRIKKTTQLKKLMNAYCDRQSVEFSSIAFLFDGRRLRAEQTPEELEMEDGDEIDAMLHQTG +>A0A674NAG5|unreviewed|Rad60/SUMO-like/50-67 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A4W6EEG1|unreviewed|Rad60/SUMO-like/50-67 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A0G2HVA9|unreviewed|Ubiquitin-like/16-91 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMEAFCSRQGKDISSVRFLFDGTRVRQDDTPDTLDMADGDTLEVHQEQIG +>J6EH81|unreviewed|Ubiquitin-like/23-97 +-HINLKVSDGSS-EIFFKIKKTTPLRRLMEAFAKRQGKEMDSLRFLYDGIRIQADQTPEDLDMEDNDIIEAHREQIG +>G1PXR8|unreviewed|Rad60/SUMO-like/54-71 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A7S0XMH2|unreviewed|Rad60/SUMO-like/93-161 +--LRVCVRCGGKEKDSFDIFANEPLSKLFAAFADDRGVPTAACAFDFDGIKLAPTQTAAQLQIEDHDMIDA------ +>A0A9P1CU75|unreviewed|HMG/1039-1093 +---------ADGNVIDFKLKSSSRLDKMMKAWCKCNGIPESDAVFEFNGRLLLPEDTPASCS--------------- +>A0A317WD12|unreviewed|Ubiquitin-like/16-91 +EHLNIKVTDNNN-EVFFKIKRSTQLRKLMDAFCERQGRQASTVRFLFDGTRVRPEDTPDTLEMTDGDTLEVHQEQIG +>A0A6G1LFQ9|unreviewed|Ubiquitin-like/23-98 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMDAFCERQGKDIRSCRFLFDGQRVNPTDNPESLDMADGDVLEVHQEQIG +>A0A8C9L7L3|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A6P5E0M9|unreviewed|NFATC2-interacting/280-349 +---QLRVQGKEKQTLEVSLPPDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLSGKELPADLGMESGDLIEVW----- +>A0AAD4FZP8|unreviewed|Rad60/SUMO-like/201-259 +--------------FGFKMRRNDAFRTMFNEVADMVSVLVDNIVVTHDGKRVYPSASPHGIGVWSEAELDACD---- +>D3Z794|unreviewed|Rad60/SUMO-like/16-51 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQ----------------------------------------- +>A0A914JQK4|unreviewed|Ubiquitin-like/21-95 +DYIKLIVVGMDGIEVHFRAKYGTRLAKLKKSYCECIGVQVKTLRFLYAGSRIGDEDTPKTLEMEENDVIKVYKEQ-- +>A0A8X8DCU3|unreviewed|Rad60/SUMO-like/80-129 +----------DGNEVFFRIKRSTQLKKLMNAYCDRQSVAINSIAFLFDGRRLRREQTPDE----------------- +>A0A813GWA6|unreviewed|Ubiquitin-like/11-86 +-HIQLKVKDQQGSEVQFKIKKSTPLRKLMDAYCSRLGLQASQVRFMVDGERIAADDTAEKLGLEDEDLIDVAMEQTG +>A0AAD7ISH9|unreviewed|Ubiquitin-like/23-95 +-TINIKVVSSTGEEVFFKIKRSTKLSKLQGAYASKVGKDVSSIRFLYDGSRIADDDTPQSLDMEDNDTIDVMVE--- +>A0A8B9HB48|unreviewed|Ubiquitin-like/26-86 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQV---------------- +>A0A2K6KX05|unreviewed|Ubiquitin-like/8-67 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQ----------------- +>A0A8C6L0I2|unreviewed|Ubiquitin-like/92-126 +-----------------------------------QGVPASTLRFLFEGQRIADNQTPKEVNMAAVALLF------- +>A0AA38FPQ1|unreviewed|Small/30-104 +-HINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQT- +>A0A9N8E9P9|unreviewed|Ubiquitin-like/184-258 +--VTLRVRDQTGEETFFKIRKNTRMYKVFETYADRKGVWVNDLRFLLDGARIEAWHTPMGLELDDQDQIDCMLEQTG +>A0A830HS18|unreviewed|Small/10-84 +--LQIKVKAQDGSEMFFKVKPSTKMGKVFAAYASKKSVEQRSVKFLFDGNRIKEDDTPESLGLENDDEVDAMLEMVG +>A0A4U0XV88|unreviewed|Rad60/SUMO-like/372-444 +--IRIYLTSKERDPFKLKVKPSTPIWKIMTACRPQFDLREQSIYLDFDGERLGSEQTVQDTEINDMDRIDVHV---- +>A0A9P3LVP4|unreviewed|Rad60/SUMO-like/57-127 +EYVMFKIRGKDTADQKIRAKKTTTVASIINHYKRLRELDPETVKLEFDDEAIDPSKMLGETEIEDDDMLT------- +>A0A397HHS6|unreviewed|Ubiquitin-like/216-271 +-----------TKPLIVHRKMSQSLRDVRLAWCNRQNLPTASIYLTWKGRRLFDVTTCRSLGLD------------- +>A0A183H085|unreviewed|Ubiquitin-like/183-234 +-----------------RWKMSETFTNIVKIYASNWSCSPDNVILSLNGKRISAEDTPCSVAFSEKDV--------- +>A0A0D6R2A8|unreviewed|Small/27-102 +-HINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A7N0UUK9|unreviewed|Rad60/SUMO-like/136-207 +-KIVISIQDKDD-LKLFRVYMDEKFEQLFSKYANKMKIDAQNLVFCFDGDKINPSATPESLGMEDDDIIEVHVK--- +>A0A6J3DBZ7|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDEDTIDVFQQQTG +>A0A2A9PU36|unreviewed|Ubiquitin-like/19-94 +EHLNIKVTDNNN-EVFFKIKRSTKLEKLMNAFCERQGKNMTSVRFLFDGTRVQPTDTPDSLEMTDGDSLEVHQEQVG +>A0A9D3LJB5|unreviewed|NFATC2-interacting/185-255 +--IPLKFRCRTD-LHKIPMQSTAPLSVAVQQLSVKLNVPTSRILLLRKDTELPVESTANELGLGIADIIDCVVI--- +>A0A1S3CZT7|unreviewed|Ubiquitin-like/283-355 +DCIEVKVQQKNVKPLLIQLHKSNDMNIFAKKVASELGIDVSKLKFTFDGDTLDLEETVESLDLDGGECFDLV----- +>A0A3Q2TUP8|unreviewed|NFATC2-interacting/229-299 +-EIPLKIRFRTD-VHKVLVLPSTRLGDAVGQLARTLQVPPARLLLLKEAQELPTGATVGELGLGIADIIECIV---- +>A0A6J0MMS2|unreviewed|Small/39-115 +-KIMIKVKSQQGGEDLYKIGENAPLKKLMTAYCVKKNLDLSTVRFIFKKKGLKPRHTPSQLKMENNDIIDTVTEQGG +>C6HIG7|unreviewed|Ubiquitin-like/18-92 +-HLNIKVTDNNN-EVFFKIKRTTQLKKLMEAFCTRQGKDLSSVRFLFDGTRVRQDDTPDTLDMADGDTLEVHQEQVG +>A0A8B8U145|unreviewed|Ubiquitin-like/76-152 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0AAD4HQN3|unreviewed|Rad60/SUMO-like/257-320 +-----------KDVWNFKMKRHDTFQYLFEELADLAAVLVDHLVVSHDGKRLFASGTPHSLRIWAEGELEACDQT-- +>A0A7S2FIU6|unreviewed|Rad60/SUMO-like/143-217 +--LTIRVQDDTGDEQIFRMRNNCRMEKLMSTYALKVGVNVASFRFYIDGERVNPLATPLELELADGGSIQCFMKQQG +>A0A8C7PWG6|unreviewed|Small/36-112 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNTLRFLFEGQRISDNQTPKELGMEDEDVIEVYQEQTG +>A0A6P6WXQ5|unreviewed|Ubiquitin-like/22-97 +-KILLKVLGQDGKMMNLEVKRNKPMKNILLKYCDYKKFEYSAVNFLYLGRRVLVRSTPEELGMEDGDIIEAMVHVDG +>A0A8H5L003|unreviewed|Ubiquitin-like/19-94 +EHLNIKVTDNNN-EVFFKIKRTTKLEKLMGAFCERQGKATSSVRFLFDGTRVQPTDTPDALEMQDGDTLEVHQEQVG +>A0A078B9T5|unreviewed|Ubiquitin-like/59-134 +-HINIKVKAQDGTEIFFKIKRTTQLKKLMDAYCTRQGLAVNQCRFIFDGERLKDDDTPDKLEMENGDEIDVMVEQTG +>A0A813RZT9|unreviewed|Rad60/SUMO-like/217-277 +DTITLKIDHSDGRQLTLSLPSSITLKNLHDQVAERLSLP--SIYLVYNNQTLKLDDNNQSMTL-------------- +>A0A7K8MXF2|unreviewed|Small/17-93 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A0A0KDV8|unreviewed|Small/21-96 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDLNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A7L0WJD6|unreviewed|Small/10-86 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8K1GIU0|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A1X2G641|unreviewed|Ubiquitin-like/18-94 +DHINLKVVGADNNEVFFKIKRSTPLRKLMDAFCERQGKAPGSVRFLYDGNRVLPVNTPDELDMEDGDTIDVMVEQIG +>A0A8H6F0G0|unreviewed|Ubiquitin-like/25-99 +-HINVKVSDGTQ-EVFFKVKRNTKFRRLMEAFAKRQGTSPDTMRFLVDGGRVHADQTPEDLDMDDGDTIEAHRAQIG +>A0A443REP4|unreviewed|Ubiquitin-like/288-352 +--------SKNSKPITLNALKAKELQNVMLEYAEIVEIEVKKLNFYFDGEKLNGNETPEDLEMEDGNLIDVVI---- +>A0A670ZAZ0|unreviewed|NFATC2-interacting/1-44 +----------------------------MNQYKEAQGLGRSKVVFYFDGQRLTETLTPEQLGMESGDVIEIV----- +>A0A8H8A4Y3|unreviewed|Ubiquitin-like/277-346 +--IELILRNENNENLKLSIDSNTIISNLIDIFKASKNIDINTIILKFEGEHLEPNLSISSYNFENGDLIDV------ +>A0A6P6L049|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8C8GNH8|unreviewed|Ubiquitin-like/16-76 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQV---------------- +>A0A4X1UKU5|unreviewed|NFATC2-interacting/69-139 +--IQLRVQGKEKQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLTFFFDGTKLSGKELPADLGMESGDLIEVW----- +>A0A0D1YLF4|unreviewed|Ubiquitin-like/356-427 +--IRIILRSKGYPDQKLIVKPDTTVERLQGAFRTANKISESNVVLVIDGDELTPDMTMEDAEVEDLNMIEVYV---- +>F6QF17|unreviewed|NFATC2-interacting/265-332 +----LKIRCRAD-LVRLPIRMSEPLKSVVDHMAARLGVSPSRILLLLGETELSPTATPRALKLGVADIIDCVV---- +>A0A663DTE1|unreviewed|Rad60/SUMO-like/51-68 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A7L1SUX2|unreviewed|Small/16-92 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0AAE1W3Y5|unreviewed|Rad60/SUMO-like/23-91 +--------CEDRDEVYYRFPRDKKLQHLFSSYCKQKKLNYDAIAFVHDGKRVKASKNPVEMEMEDGDSIDAMMHQDG +>A0A1X0RE18|unreviewed|Rad60/SUMO-like/200-258 +---------KLQKPMKVIVMNNEQFDRILTIFCNHKKLKKDDIVLVYKEGKVFLRGTPAGVGMTGSET--------- +>A0A364N1Z9|unreviewed|Ubiquitin-like/21-96 +EHLNIKVTDNNN-EVFFKIKRTTALGKLMNAFCDRQGKNISSVRFLFDGQRVTAADNPDTLDMQDGDTLEVHQEQIG +>A0AA48I2U1|unreviewed|Ubiquitin-like/19-94 +-TLNIKIRATDSSEVFFKIKKTTKLNKLKTAYADRVGHDPTAIRLLFDGARILDNQTAEDLDLEDGDVLEVLLEQVG +>A0A287D8A4|unreviewed|Small/20-95 +ECIKYKVIGQDSSEIHFKVKMTTHLKKLKESHCQRQGVPMNSLGFLFEGQRIADNHTPKELEMEEEDVIEVYQEQT- +>A0A8C6GTC0|unreviewed|Small/133-209 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A1S3C3V0|unreviewed|Small/21-96 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDLNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A6P5XD50|unreviewed|Rad60/SUMO-like/189-260 +-KIVISIQNKDE-LKQFRVYMDDKFERLFSMYADKAKLDLQSLVFSFDGDKISLAATPASLGMEDDDIIEVHVK--- +>A0A6A6S954|unreviewed|Ubiquitin-like/353-425 +-KIRLFLKAKNKEVLKVIVRPDTTVSQLTQSYKTSRHISADQITLMFDDERLKPMDVVSDYDIEDEDSIDVYF---- +>G7ZWR8|unreviewed|Ubiquitin-like/91-159 +---DLNIKDKDGIEVYFNISRSTPLKKLMDFYGYRHCLDINGVAFLFNGRLVTAEQTPDELQMMDGDEIDVV----- +>A0A024SIR3|unreviewed|Ubiquitin-like/425-497 +-KLRIKLVAKGMDVVKLSVLPETTVETLVIGFQTQRSVASKDVSIWFDGERLEEHQTMEDAGIDEMDTLEVHI---- +>A0A8H7ZCL8|unreviewed|Rad60/SUMO-like/55-130 +-RIALIVTDGVGIERQCSVKRNAPMRVVLEWYCRNPKRDVNSFRFLCDGMRIDPDETPLQLGLTDNDIIEAHHLQTG +>A0A2K5I4J6|unreviewed|Rad60/SUMO-like/20-56 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQG---------------------------------------- +>A0A3N2PMD4|unreviewed|Ubiquitin-like/450-522 +-KIRVILKTRSDEPVKTTVRPSTTIQTLVVMYRKMRNVPESSVSLYFDGEQLDEASTIEEVDIEDMDTIEVSV---- +>A0A2U1J6J9|unreviewed|Rad60/SUMO-like/464-534 +ETFKIKIRSKLGKDIYMDIAKSVKISFVIEAYKKACELNEVKVKLSFDDESLNPNDKIGDTEIEDDDMIM------- +>A0A8C7L4Y0|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A1J9PQ63|unreviewed|Rad60/SUMO-like/401-468 +----LTLKAPGIEDLKIRVRPKTHISSIIKSFREKRGIRTHSIQLIFDGDQLHPDSMVTDNDMADLDAIDV------ +>A0A8T3C4H9|unreviewed|Small/29-104 +-HINLKVKGQHGNEQTFSIKRTSNLKRLMDAYCYRQSENVNAIVFLYDGRRLRGEETPESLKMDDGDVIDAMLHQTG +>A0A8C9M758|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A821XXK8|unreviewed|Small/10-86 +EHINLKVLGQDNAIVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEVYQQQTG +>G1Q034|unreviewed|Rad60/SUMO-like/16-67 +DHINLKVAGQDGSVVQFKIKRHAPLSNLMKAYCERTKKSIRKLQFGFNTS--------------------------- +>A0A8T0B1Y1|unreviewed|Protein/273-341 +DVITLRLQGKEKSTKEYSLHKDATLGSILSQYTAGLSATKRKVKFLFDGLKVTHNQTPSQLDMEDAA---------- +>F1Q553|unreviewed|NFATC2-interacting/197-268 +-EISLKFRCRTE-LFKIPILSTAPLSKAVEQLAIKLNVPSSQILLLKKDIDLPIHSSVSELGLGIADIIDCVVT--- +>A0A096NHK9|unreviewed|NFATC2-interacting/440-510 +--LQLRVQGKEKQTLEVSLSRDSPLKTLMSHYEEAMGLSGRKLSFFFDGTKLSGRELPADLGMESGDLIEVW----- +>G1L5L1|unreviewed|Small/8-84 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A5J5MLF9|unreviewed|Small/1-57 +--------------------MTTHLKKLKESYCQRQRVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEDYQEQTG +>A0AAD7SMI2|unreviewed|Small/20-96 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVHMDSLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A5J5SZN9|unreviewed|Rad60/SUMO-like/19-51 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCD------------------------------------------- +>A0A3B3RLK0|unreviewed|Small/15-89 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQ-- +>A0A1Y3E9I1|unreviewed|Small/15-91 +DFIQLRVVSQDSKEVTFRVNMDMQLIKLMKAYSERTGIGLGSLRFVFDGSRLDDRKTPKELNMEDNDMIDVYQQQHG +>A0A023FVZ9|unreviewed|Small/13-89 +EHINLKVVGQDGSVVHFKIKKHTPLRKLMTTYCDRAGLSIQNVRFRFDGQPINETDTPAGLDMEDDDTIDVFQQQTG +>A0A1D2VMP1|unreviewed|Ubiquitin-like/2-66 +------------SKLFFKVSPTIKLKKIIQTFAKKMDVDSKSYVYFFDGERIHESNTPLQLEIQDGDSIEAKLTTHG +>A0A8H4V3N7|unreviewed|Ubiquitin-like/19-78 +EHLNIKVTDNNN-EVFFKIKRSTKLEKLMTAFCERQGKAISSVRFLFDGQRVQPADTPDAL---------------- +>A0A1S3WA99|unreviewed|Rad60/SUMO-like/16-60 +DHINLKVVGQDGSVVQFKIKRQTPLSKLMKAYCERQGLSMRQIRF-------------------------------- +>A0A8C1L697|unreviewed|Ubiquitin-like/1-49 +----------------------------MKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A2P4ZYL0|unreviewed|Rad60/SUMO-like/21-79 +EHLNIKVTDNNN-EVFFKIKRSTKLEKLMTAFCERQGKSLNSVRFLFDGTRVQPTDTPDA----------------- +>A0A9P5R1R0|unreviewed|Rad60/SUMO-like/389-460 +EYIFIKLRGKDTSDEKIRVKKTTTVNAIISHYKSIKRIPASTVKLEFDDEALDSTTVIGDTEVEDDDMLVV------ +>A0A7S1IV32|unreviewed|Ubiquitin-like/155-228 +DVISLVVISPEGDELRCGFKVSIPLSKLMDEYCSQKGLKRTRVRFRFDGRLLRYDNTAADYGMEDDDRIHAF----- +>A0AAD2NIA1|unreviewed|Ubiquitin-like/396-463 +----LTLKSPGLEELKVKVRSKTLISAIIRSFYEQRRIPARKIQLIFDGDELDPESTVADNDIADLDAIDV------ +>A0A9P9KWL1|unreviewed|Ubiquitin-like/417-486 +----IMLKGRDVEPLACKILPETTVETLISHFRQQRDVSDKEVSLWWDGERLEEHVEMKEAEIEAQDTIEVHV---- +>A0A8C0KFB0|unreviewed|NFATC2-interacting/70-139 +---QLRVQGKEKQMLEISLSPDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLTGKELPTDLGMESGDLIEVW----- +>A0A2Y9R3P0|unreviewed|Rad60/SUMO-like/82-104 +------------------------------------------------------QDSPAQLEMEDEDTIDVFQQQTG +>A0A2J8A7H8|unreviewed|Small/454-528 +--LNIIVRDQCGADVSFRVRPCAKMGAVLNAYAWKEGLDPCLLKLIFRGRRLGHLSCPAGLGLADGDIIDAMREQVG +>A0A4W5KGQ4|unreviewed|Ubiquitin-like/6-47 +-----------------------------------TGLSIRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTG +>A0A1Y1HST2|unreviewed|BTB/49-112 +-------RQKAGQTVMFKIGTSTKLRKLKRAWCTKVGVCPESVEFFHGGRTVEDQHSAADLFMLEGDLIFV------ +>A0A8D0AJG9|unreviewed|NFATC2-interacting/138-207 +--IPLKIRCRTD-VHKIQVQSSTPLSEVVTQLSGILSVPPPRLLLLREDVELPTHSTVGELGLGIADIIECVV---- +>A0A9W8NSH5|unreviewed|Ubiquitin-like/22-96 +--INVKVVSSSGEEVFFKIKRSTPLRKLLGAYANKVGKQEHTIRFLYDGARVAQTDTPKSLEMEDNDTIDVMVEQVG +>A0A452F2Z8|unreviewed|Rad60/SUMO-like/17-76 +-QINLKVVEQDGS----VIKRHTPCRKLINAYY----LLMGQIRFQVDGQPINETDTPAQSKMEDKDTM-------- +>A0A2H4S5J5|unreviewed|Ubiquitin-like/471-541 +---RVILKTRGGEPVKLRVLPETTTETLVAAFRAQRDVPQADVGLWFDGLRLEAGATLSDAGIDDMDTIEVHV---- +>G1PXR8|unreviewed|Rad60/SUMO-like/16-54 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQDIQ-------------------------------------- +>W0T6G9|unreviewed|Ubiquitin-like/16-90 +-HINLKVSDGSS-EIFFKIKKTTPLKRLMEAFAKRQGKEIESLRFLYDGVRVLPDQTPEELDMDDNDIIEAHREQIG +>A0A8H8J1C3|unreviewed|Rad60/SUMO-like/209-289 +--IVVKVVCKFRAELFFKISRKTKLTRLFTAWESRMEVSPANFIFTHAGRTVDWDQTPDEAGIENNDVIMAV----- +>A0A0L9U5A9|unreviewed|Small/22-97 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFSSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A9P6WYA0|unreviewed|Rad60/SUMO-like/297-365 +-KMIIKLRGNDKKEISVRVKPSTLLSAVTEIYKKITKVA-GDVQLYFEGEPMDLDLTIADTELEDEDLLEV------ +>A0A9Q0ANY0|unreviewed|Ubiquitin-like/66-145 +NYINLKFKESARRETVMRVERTAAIGGTLEEYARQVGKHLDVLRFIYDGQRIGSDDSPADLELEEGDIVDVLIPQHG +>A0AAD9LJS3|unreviewed|AAA+/1304-1361 +------------NMYSCLMQKTQRFSSLFRHYSKHHGLPRESLDFFFT-NRLDPEDSPESVHLQKNDVILV------ +>A0A8C8VLM8|unreviewed|NFATC2-interacting/242-311 +--LQLKVRSRAE-IHRVPVETLQPLQAVVDYMAGRLRVRPRQILLLLRDVELPPDSTPQALGLGVADIIDCVV---- +>A0A4X1U4N3|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGIPMNSLRFLFEGQRIADNHTPKELGMEEEDVTEVYQEQTG +>A0AAE1D384|unreviewed|Ubiquitin-like/100-174 +DSINVVVQCRHSSKTTISAHKRQPLKYVIELYAEKMGLDAKSLRLVFDGEDVNPSDTPYKLDIEDLDIVDVIMK--- +>A0A337SP28|unreviewed|Small/187-263 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A0B2UJ27|unreviewed|Ubiquitin-like/21-97 +-KIVLRLTDPDGTALVFKVKRNVTFRKVLEAFSKNVGKSSEEFRMVHNGKNLRDGMTPDDLGFSGNEEIEVFTSQEG +>A0A7N2KKL2|unreviewed|Rad60/SUMO-like/151-222 +-KIVISIQDKDG-TKQFRIYMDDKFERLFKMYADKVKLDLQNLVFSFDGDKINPAATPDGLGMEENDIIEVHVK--- +>A0A7E6DCJ2|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHSKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEGDVIKVYQEQTG +>A0A9E7K7W5|unreviewed|Ubiquitin-like/1-48 +----------------------------MSAYCDRRSMDFNTIAFLLDGRRLRGKQTPDELEMEDGDETDAMLHQT- +>A0A8C8CZM6|unreviewed|Rad60/SUMO-like/55-72 +-----------------------------------------------------------QLGMEDEDVIEVYQEQTG +>A0A2P4T1E2|unreviewed|Small/47-107 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEV---------------- +>A0A0N5ADR2|unreviewed|Ubiquitin-like/74-145 +EYIKLKVVGQDSNEVHFRVKYGTSMGKLMKSYADRTGVAVNSLRFLFDGRRISNEDTPKTLEMEEDDVIEYV----- +>A0A4W4E3C9|unreviewed|NFATC2-interacting/62-135 +DVITVRLQGKEKSAQEYALHKHAPLGSVLSQYMATLPVTAQNVIFHFDGSKVTHNQTPSELDMEDGDVIEVW----- +>A0AA88UM26|unreviewed|Small/25-99 +-HINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVEFNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQT- +>A0A8H4ECP7|unreviewed|Ubiquitin-like/15-90 +EHLNIKVTDNNN-EVFFKIKRSTQLKKLMDAFCERQGKQLSTVRFLFDGTRVRPEDTPDSLDMADGDTLEVHQEQIG +>A0A7J6V8S6|unreviewed|Small/21-95 +-PINLKVKGQDGQVVNFRVKKTIHLGKLMSVYCQRQSLDIKAIVFLYDGRYIKLKNTPAQLEMEDGDEIDAMLHQT- +>A0A5N4EKW2|unreviewed|Ubiquitin-like/54-130 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>D4AXQ1|unreviewed|Ubiquitin-like/381-452 +--VRITLKNPDLDDFRIKVRPSTQIGNILKKFRQVKEIPEHSVSLYFDGDKLDPDTLIEDNDIDDMDCIDVIM---- +>A0A151QV30|unreviewed|Small/22-102 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A8T2PBD0|unreviewed|Small/28-104 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNSLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A8S1VXM8|unreviewed|Ubiquitin-like/8-84 +DYLNLKVKSQDGEEVFFKIKKQTQFKKLMDAYCSRQNLQIQNVRFLFDGERILETQTPADIGMETGDEIDVVIEQVG +>A0A2G5VV71|unreviewed|Small/17-93 +EYIKIKVVGQDSNEVHFRVKFGTSMAKLKKSYADRTGVSVSSLRFLFDGRRINDEDTPKSLEMEDDDVIEVYQEQLG +>A0A2C6AHW9|unreviewed|Ubiquitin-like/21-96 +EHLNIKVTDNNN-EVFFKIKRSTKLEKLMNAFCERQGKSMTSVRFLFEGTRVQPTDTPDGLEMVDGDTLEVHQEQVG +>A0A9W8VQT7|unreviewed|Rad60/SUMO-like/419-493 +ERFKVVLKGRDMEPFSCTVRPRTTAETIITCFRQQRQISDKEVSLWWDGERLEEHIEMEQAEIEDMDTIEVHIQ--- +>A0A6P8LCA9|unreviewed|Ubiquitin-like/190-255 +----IKIQTTGKKNLTVSVKRDNDFKILLEKCAQKFDVEESKIKLYFDGELIAATDTPASLDIEDEACFD------- +>A0A3Q0SCU0|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A0P0VC40|unreviewed|Small/21-96 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDIKSIAFLFDGRRLNAEQTPDQLEMEDGDEIDAMLHQTG +>A0A0B2PTV7|unreviewed|Small/22-97 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTG +>A0A6P6NYI8|unreviewed|Small/19-95 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNSLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A2K5MNB2|unreviewed|NFATC2-interacting/1-55 +------------------MRKSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A2K3CPY8|unreviewed|Ubiquitin-like/435-503 +DRINIIVKDQSGSEVHFQVKRSTRVGKVFDAYYCAKGMDNHSCRFLYDGSHVRDHITVGQLGMKPGDVL-------- +>A0A484BB94|unreviewed|Small/11-87 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEVYQQQTG +>A0A167N5K5|unreviewed|Ubiquitin-like/28-102 +-KLRLTIQCQGQ-QCQVDVSATTLFGKVFDAAYKRFNKKKGTLRFLHDGQRIRENQTPKMLEMEHEDVIDAELEQLG +>A0A091FYU6|unreviewed|Small/21-97 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A668AP74|unreviewed|Small/16-92 +EHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTG +>A0A0V1NDF5|unreviewed|Small/15-91 +DFIQLRVVSQDSKEVTFRVKMDMPLIKLMKAYSERTGIGLGSLRFVFDGSRLDDTKTPKELNMEDNDMIDVYQQQHG +>A0A8C8C0I5|unreviewed|Small/13-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKFTFICLFCSYKQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>G2J6V9|unreviewed|Small/17-93 +EYIKIKVVGQDSNEVHFRVKFGTSMAKLKKSYADRTGVSVNSLRFLFDGRRINDEDTPKSLEMEDDDVIEVYQEQLG +>A0A6P8LRG6|unreviewed|Ubiquitin-like/222-287 +----IKIQTTGKKNLTVSVKRDNDFKILLEKCAQKFDVEESKIKLYFDGELIAATDTPASLDIEDEACFD------- +>A0AAJ6QXX9|unreviewed|Small/21-97 +EFIKLKVKGQEGDEIHFRLKMTTPFSKIKKNYAERVGVAAGSIRLIFDGNPVSDSDTPRNLSLEDDDIIEAFVEQTG +>A0A2V3J1G9|unreviewed|Ubiquitin-like/21-97 +DQINIKVRDAEGNEVQFKIKKTTQLKKLMDAYCLRMGTAKGAYRFLFDGHRINEEDTPESLDMQELDCVDAMVSQLG +>A0A3Q0G591|unreviewed|Small/44-120 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8C2TXI2|unreviewed|Small/19-95 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>C5XCC7|unreviewed|Rad60/SUMO-like/22-99 +--ITLKVLDQQSRRAFHTMRMNDRLQGVMDAYYKKVDVTYGTGIFMFDGSRLRGCNTPAELDLNDGDQIEFFESMIG +>A0A8C3WWB2|unreviewed|NFATC2-interacting/352-422 +--IQLRVQGKEKQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLSFFFDGTKLSGKELPADLGMESGDLIEVW----- +>H9GAJ1|unreviewed|NFATC2-interacting/1-54 +--------------------MTDPLQKVIEHMGQTLKVPPNRILLLLRDRELAADATPGRLGLGVADIVDCIVE--- +>A0A3Q2E667|unreviewed|NFATC2-interacting/45-95 +---------------------EAPLSSIFSQYLSGLPAAARKVRFHFDGSKVTGSQTAAQLDLEDGDIIEV------ +>S8EMJ8|unreviewed|Rad60/SUMO-like/257-317 +-----------GQLVTSKVKRHDSFHGLVEEVADAAEVMTDHVVLSYDNKRVFPSATPHTIGLWAEAELEAC----- +>A0A671VA18|unreviewed|Rad60/SUMO-like/15-50 +EHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQ----------------------------------------- +>A0A6P5PB99|unreviewed|Rad60/SUMO-like/16-54 +DHINLKVAGHNGSVVQFKIKRHTPLSKLMKAYCEQQDLQ-------------------------------------- +>A0A9P8EL70|unreviewed|Ubiquitin-like/89-165 +DRVQIVLKDQSGTQIAFGVKSNTRMEKVQNAYADRTGRPVGTLRFYYEGTRVVPEDTVATLEMENEDIIEVMTEQIG +>G4TRF1|unreviewed|Rad60/SUMO-like/241-300 +-------------KWRFQFNLTAPFRRLNEMMQQKTQLPEEDIVLVYASKRILLGATPRSLRMRKDEMIDV------ +>A0A452U2M9|unreviewed|Rad60/SUMO-like/16-49 +DHINLKVSGQDGSVAQFKIKRHTPLSKLRKVYCE------------------------------------------- +>M7U1K1|unreviewed|Ubiquitin-like/399-467 +----LKAQSKDIKEFKTYVKPTTTIKKLVDGFRSTNQIPAKKIILSFDGDHLEPESTVEEADFDDMDTVDVL----- +>A0A667I6A6|unreviewed|Rad60/SUMO-like/16-51 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQ----------------------------------------- +>A0A6D2Y845|unreviewed|NFATC2-interacting/1-55 +------------------MRKSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A284RZR3|unreviewed|Ubiquitin-like/25-100 +-SINIKVVSSTGDEVFFKIKRNTKLSKLRGAYANKVGRDVDTIRFLYDGSRIQEDDIPQSLDMDDNDTIDVLVEQAG +>A0A2Z6M7Z1|unreviewed|Ubiquitin-like/227-299 +-RISLKVTGQVGFEAFFRINRSTQLKNLMDVYCRRYCFDFDGVAFLFNGRLIEAEQTPNELGMENGDEMLAVLQ--- +>A0A2Y9IBU6|unreviewed|Small/20-96 +EYIKLKVVGEDNSEVHFRVKMTTCMKKLKEFYCQRQGVPVHTLRFLFDGQRIADNHTAKELEMEEDDVIEVYHEQIG +>C1LQV7|unreviewed|Small/12-88 +EHINIKVQGQEGSIIHIKIRKNTPLRKLMLAYCERLGLKQPSVRFIFDGNSVHETDTPASLEMEENDTIEVFQTQTG +>A0A1Y3AXN6|unreviewed|Rad60/SUMO-like/2-56 +-------------------LRTQTFSAIYDQIAKRFDVPISRFTLYLNDDIVDAKSTPQSINLSVADIFDMYVR--- +>A0AAD4BNX4|unreviewed|Ubiquitin-like/23-97 +--INVKVVSSTGDEVFFKIKRNTKLSKLQGAYAAKVGKDVSSIRFLYDGNRINEDDTPSSLEMEDNDTIDVMVEQVG +>E4YY38|unreviewed|Rad60/SUMO-like/6-76 +--IVLGVTSIDGKKHRFRIRETDTMRKLIETYAQMENVSPDSIQLIHKGQPVNGSDVPKMLDLQSMEILEVC----- +>A0A395SQD2|unreviewed|Rad60/SUMO-like/429-499 +----IMLKGRDIEPLECKVMPETTVDTLIAVFRKQRQIGTREVSLWWDGDRLEEHVEMEQAEIEEHDTIEVHVQ--- +>A0A9Q3JGK7|unreviewed|Ubiquitin-like/96-161 +------------EPLLLKVKPTTKFHKIYSTVAQHRRVEMNSFRLHYDGQRLLPNDTPADLQFDENETLDYVVEQIG +>A0A2I3RYY5|unreviewed|NFATC2-interacting/7-58 +---------------------SEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A7S0FE68|unreviewed|Rad60/SUMO-like/232-294 +---TLRFVNEQGEEIQMSCKRENWLSGLMSLVCKRFGMDPAQARFYHKDAAIGPHDSIRSLGLSDD----------- +>A0A8J5C3X1|unreviewed|Rad60/SUMO-like/189-259 +-KIVISIQDKLG-QMQFRVYLDENFDRLFKLYAEKVQVKLDKLVFSFDGEKVSSNATPEALGMENDDIIEVYD---- +>A0AAF0Y5G1|unreviewed|Ubiquitin-like/350-418 +--VRIIVRGAKGDEIRFATKVTTPASTILKYYCSKSGIAEIGLSLWWDGEAVEPTTTLEELDVENGDIVEV------ +>A0A6P8NIM4|unreviewed|Ubiquitin-like/237-302 +----IKIQTTGKKNLTVSVKRDNDFKVLLEKCAKKFDVEESKIKLYFDGELIAATDTPASLDIEDEACFD------- +>A0A7M7PB85|unreviewed|Ubiquitin-like/271-340 +--VTLRTREKNCKTITKKLAKMETFETVFQAFSELHNKPIHQLHFSFDGDDVAPTATPQDLDMSEENVIDVI----- +>A0A0D2KFP6|unreviewed|Rad60/SUMO-like/13-56 +EALNIVVKDATGNEIQFKVKTTTKFGKIFSAYAQKKNLDVRSIK--------------------------------- +>A0A8B6YK95|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>G3I7M7|unreviewed|NFATC2-interacting/262-330 +---TLKIRCRAD-LVRLPVLTSEPLQNVVDYMANHLGVSPSRILLLSGETELSPTATLRTLKLGVADIIDCVV---- +>A0A2K6Q379|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0D2P6|unreviewed|Ubiquitin-like/8-84 +EYLNLKVKSQDGEEVFFKIKKQTQFKKLMDAYCSRQNLQIQNVRFLFDGERILETQTPADIGMETGDEIDVVIEQVG +>A0A915H8L8|unreviewed|Small/14-90 +EYIKLKVVGQDANEVHFRVKYGTSMGKLKKSYADRTGVSVVSLRFLFDGRRIADEDTPKSLEMEEDDVIEVYAEQLG +>A0A4Y9YUR0|unreviewed|Ubiquitin-like/21-91 +--INVKVVSSGGEEVFFKIKRNTKLSKLQGAYANKVGKDVGSIRFLYDGSRINDDDTPASLDMDDNDTIDVMA---- +>A0A7L0IME0|unreviewed|Small/11-87 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A287BF16|unreviewed|NFATC2-interacting/350-420 +--IQLRVQGKEKQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLTFFFDGTKLSGKELPADLGMESGDLIEVW----- +>A0A2K5E4T4|unreviewed|NFATC2-interacting/344-415 +-QLQLRVQGKEKQTLEVSLSRDSPLKTLMSRYEEAMGLSGQKLSFFFDGTKLSGRELPADLGMESGDLIEVW----- +>A0A8D1RQ37|unreviewed|NFATC2-interacting/350-401 +--IQLRVQGKEKQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLTFFFDGTKLS------------------------ +>A0A118K7H7|unreviewed|Rad60/SUMO-like/58-76 +----------------------------------------------------------QSLEMEEGDEIDAMLHQTG +>G0MXC4|unreviewed|Small/19-91 +--IRITVQGQGNFNAVFRIKYNAPLFKLGKEFARVADISEYGIRLFYDGQRIGENDTAKSIGLEENAILEVYQEQ-- +>A0A384AGD1|unreviewed|NFATC2-interacting/266-333 +----LKIRCRAD-LVRLPIRMSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A8H7L831|unreviewed|Ubiquitin-like/13-84 +---NLTINY-EGQTITVKVRANTAFTKIFQAAEKKFGKEPGTFKFRSDDQRLRPEQTPAEVGLEDGDQIDAYLEQV- +>A0AA88DC41|unreviewed|Small/20-95 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRAEQTPEELEMEDGDEIDAMLHQTG +>A0AAD8Q8L2|unreviewed|Ubiquitin-like/407-479 +-KIKVLLKTKTDEPLKTSVRPSTTIGTIMELFRKMRGLAADAISLRFDGDELQEDMTVEDADIGDMETIEVYI---- +>A0A8D1RN31|unreviewed|NFATC2-interacting/270-336 +-----KIRCRAD-LVXXXXXXSEPLQSVVDHMATRLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A8C7SVT0|unreviewed|Small/15-89 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQTN-- +>A0A8B8VVM2|unreviewed|Rad60/SUMO-like/14-49 +DHINLKVAGQDGSVVHFKIKRHTPLSKLMKVYCEXQ----------------------------------------- +>A0A6P8TDQ6|unreviewed|NFATC2-interacting/173-242 +--IPLKIRCMTH-VHKIPVLSSTPLSDVLTRLSVILDAPPPRLMLLRKEEELPANSTVGELGLGIADIIECVV---- +>A0A093Q4A6|unreviewed|Small/11-87 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A9P8QY87|unreviewed|Ubiquitin-like/458-529 +--LRVRLRAKDMEDVKLTVLPETTVETLIIGFRTQRHISSKDVGIWFDGERLEEHQTMEEADINDMDTLEVHT---- +>A0A6P3RAA4|unreviewed|NFATC2-interacting/277-344 +----LKIRCRAD-LVRLPIRMSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVV---- +>A0A8C7CEI3|unreviewed|Rad60/SUMO-like/44-61 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A074W5K3|unreviewed|Ubiquitin-like/89-165 +DRVQIVLKDQSGTQIAFGVKSNTRMEKVQNAYADRTGRPVGTLRFYYEGTRVVPEDTVATLEMENEDIIEVMTEQIG +>A0A5C3N0R7|unreviewed|Ubiquitin-like/16-89 +--VNLSVIY-DGQSTTVKMKINTPLKKIFDAVEKKFAVPEGTLRFFADDKRLRPEETPADVGLEDGDQIDAHLEQLG +>A0A7K5DIP7|unreviewed|Small/11-87 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A6J2VZ36|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>B4R1E9|unreviewed|Rad60/SUMO-like/346-415 +--FQVKVQDKWKYPLVIPMKKTDNFKILFIKCAEELNCDPRSIKLFFDGDVLDPNDTPNNQDMEGNEVIDL------ +>C9ZPI0|unreviewed|Ubiquitin-like/34-107 +---AVKVVNADGAEMFFRIKSRTALKKLIDTYCKKQGISRNSVRFLFDGTPIDETKTPEELGMEDDDVIDAMVEQTG +>A0A2S3HNN1|unreviewed|Small/17-92 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDMNAIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A0D2PRX1|unreviewed|Rad60/SUMO-like/66-123 +-RITIHIQSQDENRLAFKIMPNLKLSKMFHEYCQRKQYDLRTVRFFHEGRRLLGKYTAA------------------ +>A0A9W6XZI8|unreviewed|Ubiquitin-like/22-98 +EAITIRVKDQSGEETFFKVKPNTKMEKIFSAYAQRKGVPASALRFLLDGTRISGDQTPKMLELEDQDQIDCALEQVG +>A0A5P1E0W7|unreviewed|Small/18-93 +-HINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEMEEGDEIDAMLHQTG +>A0A5N3XK55|unreviewed|Small/8-84 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A067BTQ2|unreviewed|Ubiquitin-like/238-312 +DIIRVKVRRTGGKIEIYRISSSMPVQKLLLSFCNVHKLSPDHVTLKLLGDTLELDKTVSYYSLDATDVVEAACDQ-- +>A0A2B7XT89|unreviewed|Ubiquitin-like/20-95 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMDAFCERQGKQLSTVRFLFDGTRVRPEDSPDTLDMADGDTLEVHQEQIG +>A0A7K6TS06|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A8C6D5M1|unreviewed|NFATC2-interacting/70-139 +---QLRVQGKEKQTLEVSLPHDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLSGKELPADLGMESGDLIEVW----- +>A0AA40FAE7|unreviewed|Ubiquitin-like/24-99 +EHLNIKVTDNNN-EVFFKIKRSTKLEKLMSAFCERQGKTLSSVRFLFEGQRVQPQDTPDTLEMADGDTLEVHQEQVG +>A0A835LE51|unreviewed|Small/45-112 +---------KDGNEVFFRIKRSTQLRKLMTAYCDRQSVEFNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A8C9JW03|unreviewed|Rad60/SUMO-like/55-72 +-----------------------------------------------------------QLGMEEEDVIEVYQEQTG +>A0A9L0K3V3|unreviewed|Rad60/SUMO-like/57-92 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQ----------------------------------------- +>E9H3D4|unreviewed|Small/15-91 +EYIKLKVVGQDSNEIHFRVKMTTQMGKLKKSYSERVGVPVTSLRFLFDGRRINDDETPKQLEMENDDVIEVYQEQTG +>A0A9P3NBY0|unreviewed|Ubiquitin-like/35-109 +EAILIKIVSDKGEEVQYKVKKGAKMQKVFDTYEKKVGAPPGSLRFTFHGERAQGKDTVEVIGLKQNSVLEAHQFQ-- +>A0A7S1EGA2|unreviewed|Ubiquitin-like/54-134 +EQLDLVVKYQDGDPITFKIKKQAKFSKVTAAWGRAKSLDPNEFRWVPEGQRIGSNKTIDELRLEDGDQIEVFAMQVG +>A0A7S4V400|unreviewed|Rad60/SUMO-like/192-244 +----------GQAVMDFKMRPTTPFLKMMRAWCQHQELELDQARFELDGRELRPEDTPQSCGF-------------- +>Q4RMW7|unreviewed|Small/16-92 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A9P8I5C7|unreviewed|Rad60/SUMO-like/401-474 +DSVRLFLKSKGYPDFKLIVNPTTTIARVISAFRSHNKIDIDKVSLQFDGDKLDPELTIADTELGDLDHVDVYV---- +>A0A1A8JBC3|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A151IG14|unreviewed|Ubiquitin-like/44-112 +-EIDVKIYWRSNRIDRLNMRRHDNFKGIFEHYANLEGVSVNEVLIMKKDKIVHHTDTPASLEISIIDILD------- +>A0A0E0LMI7|unreviewed|Ubiquitin-like/220-288 +--VTLSVKDRKGRSITRTMRRFDALDVLFDLYFAMLPSSPKEGFFMFRGSEIDGSSSPANCDMENGDEIS------- +>A0A7E6FTB9|unreviewed|Ubiquitin-like/271-330 +------------EVKRFEMNYNDTFCQLFADLARDLQVTEDRLILLLNDTTIHQNESPASVQLRVSDILVCL----- +>A0A834X3I7|unreviewed|Small/17-93 +DKISISIKGQDGRELFYQVRRYTQLIKVMRSYCDRRQLQFETIRFIYRGKRLRPTQTPTSARLKDGAQIDAMRHQEG +>L8ICZ5|unreviewed|Small/14-90 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0AA38PFZ3|unreviewed|Ubiquitin-like/27-103 +ETINVKVVSSSGDEVFFKIKRTTQLRKLLGAYANKVGKDVNTIRFLYDGTRISETDTPHSLEMEDNDTIDVMVEQVG +>A0A3P8YU07|unreviewed|Small/20-96 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNSLRFLFEGQRISDNQTPKELGMEDEDVIEVYQEQTG +>A0A067PFC5|unreviewed|Ubiquitin-like/18-85 +---------FEGQQTQVKVKTNTQFTKIFEAVEKKLGKAPGTLRFAYDGERVQKHETPGERGMEDGDVIDAMLEQLG +>A0A7K5HX87|unreviewed|Small/9-85 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDEDTIDVFQQQTG +>A0A2S7NTV9|unreviewed|Ubiquitin-like/1-50 +----------------------------MAAYCEAKSINQDDVRFLYDGERLKGTETPESLKMDDEDRIDVFLTQIG +>A0A1S4FZI7|unreviewed|Rad60/SUMO-like/419-488 +-EIALKVQSDRKKPLEVKIRKDNKMMILIIKCAEELKCQPGDIKLSFDGDPVALDSTPVDLELEGGEILD------- +>A0A7L4H9X8|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A1W5CS56|unreviewed|Ubiquitin-like/395-468 +EQVRIILKAKGLDDFKLKVKPSTPISKIMNAFRSTYGVEADEVFLLFDGERLERGSRVGESDISDMDSIEVHI---- +>A0A7K5GGG4|unreviewed|Small/12-88 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A8C9W6U9|unreviewed|Small/11-87 +EYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNSLRFLFEGQRIADSQTPKELGMENEDVIEVYQEQTG +>A0A7K8T4J6|unreviewed|Small/17-93 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A1R3HL92|unreviewed|Rad60/SUMO-like/22-81 +DRVRLTMAGQDGSRVLYRVRRNYRFFRLFQDYCKKKNLDYQTARFLLNGHRIQGKSTPEK----------------- +>A0A9R0RJ93|unreviewed|Rad60/SUMO-like/166-238 +EKICIMVQEKDG-RQQFRVCKDEKFDKLFKAYAKKVQVSPSDLTFVFDGDKINPASTPQDLDLEDEDMIEVHHK--- +>A0A1E3IZ33|unreviewed|Ubiquitin-like/114-186 +-TLNIRIVNSNHEEVFFKIKRKTKLNKLKIAYADRVGTDVNAIRLLFDGARILEDQTADDLELEDGDALEVQLE--- +>A0A4S8K0E0|unreviewed|Small/18-93 +-HINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A2U3WA11|unreviewed|Small/20-96 +EYIKLKVIGQESSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A1R3JDP8|unreviewed|Ubiquitin-like/228-297 +--IVVKVHDLMKDHIFYWFGRKTPFHYLMLDYSDRNYLLYEHMGFFYSGKFMEPNETADDLEIEDGNVILA------ +>A0A1U7Q306|unreviewed|NFATC2-interacting/342-413 +-QLRLRVQGKEKQMLEISLSADSPLKVLMSHYEEAMGLSGHKLSFFFDGTKLSGKELPADLGMETGDLIEVW----- +>A0A9Q0Z4J9|unreviewed|Ubiquitin-like/141-211 +-KIVVSIQDKDE-VKQFRVYKDEKFERLFKRYADKAKLQIESLVFMFDGDKINLTATPDSLGMDDEDIIEVLA---- +>A0A8C5CAL5|unreviewed|Small/16-92 +EHINLKVAGQDGSVVQFKIKRHTPLNKLMKAYCERQGLSLRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTG +>A0A0V0VG03|unreviewed|Small/23-98 +DFIQLRVVSQDGKEVTFKVNIDVPLIKLMKTYSERTGIGLGS-GFVYDGSRLDDTKTPKELNMVDNDMIDVYQQQHG +>A0A2U3VFM0|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTG +>A0A9B0X265|unreviewed|NFATC2-interacting/263-330 +----LKIRCRAD-LVRLPVRVSEPLQSVVDHMAAHLGVSPGRILLLFGDTELSPTATPRTLKLGVADIIDCVV---- +>A0A8B8W5J6|unreviewed|Rad60/SUMO-like/48-71 +-----------------------------------------------------QQDTPAQLKMEDEDTIDVFQQQTG +>A0A3Q1C2V4|unreviewed|Small/20-96 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTG +>A0A8S0TY52|unreviewed|Rad60/SUMO-like/17-56 +-YIHLRVKGQNGNEEYFKMKRGAQLRKLMTAYCERRSLQFD------------------------------------ +>A0A7N0TYP4|unreviewed|Small/19-90 +-HINLKVKGQ----VFFRIKRNTQLRKLMHAYCDRQSVEMNSIAFLFDGRRLRQEQTPDELEMEDGDEIDAMLHQTG +>A0A444G4Q2|unreviewed|Small/18-93 +-HINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNAIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A9D3UWR8|unreviewed|Ubiquitin-like/27-101 +--IQVCVKSQDGNKVVYNIKRNAKLIKLMHAYCRKKQLDIHTVRFIYEGHRVPGKYTSDQLNLEDGAEICCMFHQSG +>A0A6P6UYZ1|unreviewed|Rad60/SUMO-like/163-234 +-KIVITIQDKDG-PKQFRVFMDDKFERLFKMYAEKVKLDLQNLVFCFDGDKISPTATPAGLEMEENDIIEVYVK--- +>A0A167N5J2|unreviewed|Ubiquitin-like/62-137 +-KVQIIVKFDDEQQMRVNISRSVPFSKVFYAVETRFRKQSGTVRYHYDGERVNPEDTPTSLELEDGAVIEASLFQIG +>A0A8C9Y378|unreviewed|Small/15-91 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCDRQGLAIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A674E6L0|unreviewed|Rad60/SUMO-like/55-72 +-----------------------------------------------------------QLGMEDEDVIEVYQEQTG +>A0A6G1M847|unreviewed|Ubiquitin-like/415-486 +--MEITLKGKHFKELQLKVKPSMKISEVIEKMRDERKIDEDEIELHFDGEELEEDMTLEDAEIEDEFQIDVVL---- +>A0A2I2YPD1|unreviewed|Ubiquitin-like/88-128 +------------------------------------GLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>N4UP42|unreviewed|Ubiquitin-like/19-94 +EHLNIKVTDNNN-EVFFKIKRTTKLEKLMGAFCERQGKATSSVRFLFDGTRVQPTDTPDALEMQDGDTLEVHQEQVG +>A0A8C8YKB6|unreviewed|Rad60/SUMO-like/51-68 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A7L4ESQ2|unreviewed|Small/10-86 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A1U8P6V6|unreviewed|Small/18-98 +-HINLKVKGQDGNEVFFRIKRSTQLKKLINAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTG +>A0A667I6A6|unreviewed|Rad60/SUMO-like/51-68 +-----------------------------------------------------------QLEMEDEDTIDVFQQQTG +>A0A8R1DYY1|unreviewed|Ubiquitin-like/109-188 +---IVKAQFKNRKPVLIKVQDETTVGKIKELILEQLEEEKEAMRVIFDDEYLTDDSTCQDIGIENEDCLDIHVQ--- +>A0A4S9RTU6|unreviewed|Ubiquitin-like/96-172 +DRVQIVLKDQSGNQIAFGVKSNTRMEKVQNAYAEKTGRPVASLRFYFEGNRVTADDNVTTLEMENEDIIEVMTEQIG +>A0A067N840|unreviewed|Ubiquitin-like/22-97 +-TINIKVASSTGEEIFFKIKRSTKLSKLQGAYANKVGKDVGSIRFLYEGERINNDDTPASLDMEDNDTIDVMVQQVG +>A0A8S9QYB6|unreviewed|Rad60/SUMO-like/24-83 +-KITLKVKTQQGREDVYKIGYNAHMKKLMDACCTKRNFEKDTVRFIFGRKELKPRQTPAQV---------------- +>A0A7K7XJW1|unreviewed|Small/17-93 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTG +>A0A8C9VVE4|unreviewed|Small/14-90 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A409VNE2|unreviewed|Ubiquitin-like/18-84 +---------YDGTQITVKVKTNMKFSKIFEAAEKRFGKDKGTFKFTYDGQRVKPEQTPAELEMEDGDQIDAFLEQV- +>M2Z5V1|unreviewed|Ubiquitin-like/74-149 +-SITITFRDHRGFEQSFKLKTSTKMGKAMDAFSAKVERDRKALRFLFDGERVLDGSSVGELGMEDGDTVDVLEEQIG +>W6Y0G5|unreviewed|Ubiquitin-like/234-295 +---------PNTNPLMVKIRVDTFIEKPRKAWCAKQGLSPDNVFFTWKGTRIYDSTSITRLGITVDDG--------- +>A0A195CKR3|unreviewed|Small/19-95 +EHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRVGLAIAAVRFRFDGQPINELDTPTSLEMEEGDTIEVYQQQTG +>A0A3Q1FHZ5|unreviewed|Small/16-92 +EHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>G4ZG23|unreviewed|Rad60/SUMO-like/115-184 +-RITLHIRSNGGVVDEVGIHKKETFDQLYASFCELQGLPREAVQMALDGEPLPLTGTPESEDLDSGDIIEA------ +>A0A9P6JKS4|unreviewed|Ubiquitin-like/11-84 +--LHIRVVFNHQ-TVDFMIKPNKPLAKVFDTFATKLNLDIGSLRFHAEEQRLYAEMTPEQAGLSDGDQIDVVLFQEG +>A0A1J9QSR1|unreviewed|Ubiquitin-like/17-92 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMEAFCSRQGKDISSVRFLFDGTRVRQDDTPDTLDMADGDTLEVHQEQIG +>A0A1M3TBL8|unreviewed|Ubiquitin-like/216-278 +----ITSKIPNTKPLIVRRKMNQPLKDVRLAWCNRQKFTKESVFLTWKGKRLFDVTTCRSLGIH------------- +>A0A6G1D2E2|unreviewed|Ubiquitin-like/28-106 +EYVTLKVQDTDGCVVYCTMRRTGQLQALMDLYYDRARVQRGTGRFLYDGRRLRGWQTPEELYMEDGDEVDFFTELLG +>A0A3M7AMI4|unreviewed|Ubiquitin-like/26-102 +DQLTLKFRDMNGFSIDFKLKPITKLGKAMTAFSARLQKDTKELRFLSEGRRVLPDQTPSDLELEDGDEIDVHMEQIG +>A0A1A6A2L6|unreviewed|Rad60/SUMO-like/14-91 +----IEIKPTDNPTIPFKVKRDTPFIKIFRAYEAKLGVAKNTYRFHYDGTRIDPQHTPKTLEMKIGKDIEAFNEQLG +>A0A4W3HR83|unreviewed|Small/45-121 +DHINLKVAGQDGSVVQFKIKKHTPLSKLMKAYCERQGLQIRQIRFRFDGQPINETDTPAMLEMEDEDTIDVFQQQTG +>A0A4T0QYT5|unreviewed|Rad60/SUMO-like/451-527 +-RIRLTLRGANREEYKIQISKEKKCTVLLNSFLTYFKIDQNSYKLDFDGEKLDLDTAIRDTDLEDEDLISVIKN--- +>Q8VZI7|reviewed|Small/27-101 +-KVTLKVKNQQGAEDLYKIGTHAHLKKLMSAYCTKRNLDYSSVRFVYNGREIKARQTPAQLHMEEEDEICMVMELG- +>A0A8C4I5S7|unreviewed|Rad60/SUMO-like/20-55 +EYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQ----------------------------------------- +>A0A6B2FAX6|unreviewed|Small/16-92 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTG +>A0A5N5PKF8|unreviewed|Ubiquitin-like/28-103 +EHLNIKVTDNNN-EVFFKIKRNTKLEKLMLAFCERQGKTLTSVRFLFEGQRVQPTDTPDTLEMADGDTLEVHQEQVG +>A0A1S3R6Q7|unreviewed|NFATC2-interacting/215-285 +-EITLKFRSRTD-LYKIPVLTTVPLSKAVEQLSVKLKVPPSRILLLRRDIELPVHSTANELGLGIADIIDCVV---- +>A0A1G4I0Q6|unreviewed|Ubiquitin-like/34-107 +---AVKVVNADGAEMFFRIKSRTALKKLIDTYCKKQGISRNSVRFLFDGTPIDETKTPEELGMEDDDVIDAMVEQTG +>A0A6P8E8U6|unreviewed|Rad60/SUMO-like/143-214 +-KIVVSIQDKDG-VKQFRIYADDKFQRLFKLYADKAKLSLTSLVFSFDGDKISPTATPESLGMEDNDIVEVCTK--- +>A0A6A6P536|unreviewed|Ubiquitin-like/22-97 +EHLNIKVTDNNN-EVFFKIKRTTQLKKLMDAWCERSGKSPASVRFLFDGTRVGAHDSPETLEMQDGDTLEVHQEQIG +>A0A7L3BHN1|unreviewed|Small/9-85 +DHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDEDTIDVFQQQTG +>A0A8R2ASP2|unreviewed|Rad60/SUMO-like/204-268 +EELSVKVYWKSSEIFKFQIRKYQKLKPIFDHFGNKENISNEKLYFTYNDVVIKIDDSPDSIGYNI------------ +>A0A830CRE8|unreviewed|Ubiquitin-like/1-49 +----------------------------MNAYCDRQSVDFNSIAFLFDGRRLRVEQTPDELEMEDGDEIDAMLHQTG +>A0A8H3PHP7|unreviewed|Ubiquitin-like/21-96 +EHLNIKVTDNNN-EVFFKIKRTTALSKLMNAFCERQGKAPSSVRFLFDGARVNPADSPDSLEMADGDTLEVHQEQIG +>A0A396GDL5|unreviewed|Ubiquitin-like/81-155 +NYINLHVKDTDDIKLYFRLKKTTQMRKLMDSYCDRNALDFYLMVFLFNGRRIYPHQTPYELDLEDDDAIDAVLHQ-- +>A0A8D2MEQ0|unreviewed|Rad60/SUMO-like/16-53 +EHIELKVAGQDGSVVQFRIKRHTPLSKLMQAYCVCQGR--------------------------------------- +>A0A8C3WWB2|unreviewed|NFATC2-interacting/271-338 +----LKIRCRAD-LVRLHVRMSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPAATPRTLKLGVADIIDCVV---- +>A0A2P2H5S3|unreviewed|Ubiquitin-like/330-397 +------LKCPRSGDMELNVNPRMQISRLVTIFRDAKKIPEREVYLVFDGDRLDPCSCLSMHDMADGDLVDVVV---- diff --git a/tests/data/protein-matching-PF11976_small.fasta b/tests/data/protein-matching-PF11976_small.fasta new file mode 100644 index 00000000..21b5c0aa --- /dev/null +++ b/tests/data/protein-matching-PF11976_small.fasta @@ -0,0 +1,4022 @@ +>A0A9P9SJQ2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2042821 +MDDDFGDISAEEAPAPPPPQPKAKRSLFAKKITTKVPESAEPVDFFSRAKDIYHQQRAEEERRRQKKLVKLERKRSSMSA +EVKEGSPSGEKRRRVSEHREGYSSDDGAMNHDVGIGEGHRDSAHSSQGRGRYQNQTTPTSLSARYSKDLSARRSGSPKQN +DLAKGYVSLSDSDGDDASASEEEIQRISTKLPVRKVTTQPISLGDDDDDFSIAPRKAQPQPVEEEAEFSDEEFPELVAAA +KERARQHAAQKLAAQQAFAKQDHSDLDGDDIFETGAPTKNLDPVVDILITSKIQGSKPLAVKRKLYGKLREVRWAWCDKQ +LFDGQKMTPEMKDTVFLTWKGNQLFDWSDCSACVDGGGKLSMNNTDDGKVHLEAWTQDTFDAWKKGHEAKQRGERENSED +EPVVEPAPVQRTRLIMKSREYPDYKLQVKAVTTIQKMIDAFRSAKDVPDEKEITLHFDGDKLDPEERVEDTELGDMDSVE +VHIQ +>A0A1U8J3V8|unreviewed|Small ubiquitin-related modifier|taxID:3635 +MTGVTNQEEDKKPADQTAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFNGRRLRGEQTPDELEM +EDGDEIDAMLHQTGGTMA +>A0A0B7NQM0|unreviewed|Ubiquitin-like domain-containing protein|taxID:35722 +MSAEGSKVEKKENATEHINLKVAGSDSNEVFFKIKRSTQLKKLMDAYCERQGKQSNSVRFLYDGTRILPGDTPSELDMDD +GDSIDVMVEQIGGY +>F2S3T9|unreviewed|Ubiquitin-like domain-containing protein|taxID:647933 +MADLPPQSMPAPVEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCERQGKQPSTVRFLFDGTRVRPDDSPETLDMQDGDT +LEVHQEQIGG +>A0A4Z1K661|unreviewed|Ubiquitin-like domain-containing protein|taxID:87229 +MHSPTPDPQTPIPASREHKPQPGASSGADTGKPKTVSVTVKDQLGDEITFKIKRNKPMSKIMEAYCQHKEIGDIQSVRFL +YDGLRIEKEHTADSLEMDVEARLDVFLEQLGGAR +>A0A481Z2I6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2506586 +MISFFIKNNNGENVMFLVNGTTEWSCVEKAYRDRQCVGLGNFVYNGVTLNSDTTVNEIGIQDEDVIQFINGVISYESHMQ +LTRLRMRSYIYRKSLEYV +>A0A3Q0IW51|unreviewed|Ubiquitin-like domain-containing protein|taxID:121845 +MEGTSVPYGWVHKESLNSVKVKQKDSLNSVNVKQSSSSLSGPKGQSMKASFNSSMDDEDDDFDFYSNPAAQYNKIKEQKE +KEAAAKRKLLEQKFDDEEFMNESLSLEEESGKDNPASEQNTKDNIPPVVVVDNIIEITDSQSPKNYTEESYEEEKISSNR +RTTRSSTRRRGRGRGSKSTSIFSGGLVNKRNSRKTSLDKGIERLEEVASKLKAVRNNNVPIVLNDSPVLLDSDNECDDSE +EIVNVKVVWRHGEPHSFPIMKKKDLGSIYEFFAKQENVSIQNILLSKNEKVLSPHSTPLSIEYKVTDILEGGILQNGIQK +PSNNQHDKDCIEVKVQQKNVKKPLLIQLHKSNDMNIFAKKVASELGIDVSKLKFTFDGDTLDLEETVESLDLDGGECFDL +VILS +>A0A2H5P5J8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:55188 +MADLTEVDDLEPLFDYHRVQPHNLVFLDDDDTPPIPCPKRTKVGKNVGVDMRELEVVDCEEEEEEEDWLPPPPKVMVQKQ +LVEDSAIKELRLKKQELVSFAKSADDVIRAVEESVKRKLDSSMPAALEAESEEVSKPAVERAKIVVSIQDKGGLKQFRVY +ADDKFERLFKMYADKVNLDQENLVFCFDGDKIGPEATPASLEMEDNDIIEVHTKKT +>E1Z6B2|unreviewed|Small ubiquitin-related modifier|taxID:554065 +MALSWCPQLDRGTMEQSGENTNEDVKKEAPGDAISIKVKDQSGGEVVFRVKGHTKFEKIINAFCQKKSVDPAQVRFVYDG +NRVNPQATPDSMEMEEGDTIDAFLEQVGGGSSVRSAC +>A0A1Q9C3R7|unreviewed|Cyclic nucleotide-binding domain-containing protein|taxID:2951 +MASEFLTRLTAAQLPVEILALTLEFSASLDATCAVAALEAIAQHPDRENVRRDMRFARLVFDLDGLARRRAFRARLVPRA +LAAVRKLGLRQPALVGALCVNITNRIEELPVSVLPQLLSDLAGCSVGPLTALEALTTALSQSLHTYDSSAVGEVAEALST +LRFRSERCLAALFDVTSDLGKFQAEALTKILWCLDTFGKRTQVEELAGRAFGRLSDLEDTGRSQLIDCIGILGPLQTRGD +FDQQTLQPLAASLARLASGAAVGRSFDVRVPHLGPRHTARALRAMGVQVSTFQTHSLPKWVAAARSLVAEVFGEEGPLPM +LPISKERSRIPVVEKEAYAQSIQRFGVDNFGKIGGRCLMNQLGIGRAEEAWLHEVKHFLRAWSEDVTLAIKLTELNTSWQ +ADMLRCLTAQRSAVLREVSDAALGAVSRRCSNLESIDVSGCKKISAAAMVDTVRRCPSLKTLIAVGCLGLASRVDSVRGW +DAIRKAKPGLEVINHTRDLTICALYEGSELWFTLAQHRTLDRLMDVWCARKELLPWMVQFVFEGRPIARSDTCASLSLEE +GDQLEVLWLQATSQTVRLDTHETLAPLRPRRRRILKTQWVMTHCKRRGRRMGGVFGFSMEKWCVGTVSSDWKAQTAHRRI +YAFAEFSFASTFLPGKSLLEGTLFQLNGLHADPEFTFRPWLCAVQLPISKWVDRSLCAEFQLLGEVCELLHRSGMDLTCP +ELRYSVHGDLNMYLSEPSCVSCVGSEGHPESLIARRWPPCGVSERRLCGGLLAMGIDMDGMTFSEFTGHRLQHVCDTTSR +KLEAILREQLQKATFDLKEAHRLHCKTLQQTLTHAGGELDSLRVDHFRIDGDEVPRSQPRRRIDDPDWRAEDWKAESEDG +GPDEELDFSKLRIKSPSLDSPTGSGSLQHFTSRVTFDGVGVDDLSPLSPSSGAGMPRQTSEVTLHKVWTPEDAMMTRAAS +KRLHFEDRKPANRSRSRVRSGQEILDEGCSHYVVLRPNGFFCIFWDIVCTVAIAHDTVMIPLLSAFPINQAGVPEILEAV +SGCVWMTDILISFLRGFIDTQRGLVEMRLRYIAYRYVSTWFLPDVSMALVDGLSLFLVEMRDVEALTLLRLFRNLRLVRL +LKMTDRFRLFKDVIISLGYGSEWTSVYMETGVGVLKHLAFIALLCHFTGCAWHAIGGLPGMTTWVIAHKSWREQEISVFE +HDWLYMYMTSVHWSLTQFTPAAMDVVAVNALERIFSVVVTLAGLIVFSFFLGSINQNLARLRSLHAQERLQNRLVRGYVS +ERHISVELGAEILAWIKQRRRGKANSKTVFGDIKALENLPTNLLTELQQEVGMPVLESHAMLKHLAGLGYQDAVRLCTKA +LKEVSTVFGEELFYSGAIGDKMFFVRSGRLNYMWDLKPKEIEDVLPQGRVGEATLWLQLEYSGRLACADHSAHLFFLDAT +AFRKVLAKSENMEVLTVYARLFSKLFLEQKDMGLASDLFGDDSHVAKLMRRLRTLQVGASILITADASIITAKPIFLAWK +AVAQAKHQRSKGLCWPFLNRDTECRKEKEGAMKQFQTLLPGANLFVECGSVIEPLTARRQPSSRAG +>A0AA88SGK6|unreviewed|NFATC2-interacting protein|taxID:64152 +MAEARCDGEMKSVKPPAKRRRILDPSAIVPVPIYSNKVNSSLQLKPMTPLFTEKDSTDIGADDSLCSGFSSRETANVIFL +DSEEDEPEDAEKQHEKTEQETVCCPSPPPPESPVQKQSRQVKQKLNEIDRKLRAVSSLLSPECPKRTRSRCRRGHSSASL +EEEQHDEDVIIITPDSKSESLQYSSSDREIPLKIRCRTDVHKIPVLSSTPLIDVVTQLSIILSVPPSRLLLLREEVELAT +HSTVSELGLGIADIIECVVMAAEERTGAIDDSSDSNVTVRLQSKDRDSSQMFSLHRDAPLGTIFTQYLSKMSAVNQRKVR +FHFDGSRVTHNQTPAQLTMEDGDIIEVWT +>F1LD33|unreviewed|Small ubiquitin-related modifier|taxID:6253 +MADNESQAAGDSTAPAAPPAVLESLKLKVVGQDGGEMHFRVKYGTRMAKVKESYANHLNLVVGALRFIFDGRRISDDDTP +EALGMEDEDVIEVYQEQTGGGITKIE +>A0A8H4W5S5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:354080 +MDDDVFGEDPQAPKPAPVKKSLFNLVKSXEVFPQRLAEEERKRQKKIIKLERKRSSASAEIKETSPPVDKKRRVSTNNTY +SSDEELVDTSRARRDSSHSTPGSRKSRSHSVQKSQASPTSLSERYHSALRAQKQDQLEPKKVEKGCISLSEGDNDDESSP +PADIVILDDGEGDYVPYRRKPPPLKDDDDGLSDEEFPELLEQARQREKQKALLKENASKVSEKNHNPVAGTFINDDIFQL +SGPVASDDPTIEILISSMIDGSKPLVVKRKLSQRLKEVRLSWCDKQALQGLPMTPEVKDTVFLTWRGHKLYDFTTCSALG +LKIDTLGKLTADGAGVDDNGRVHLEAWTQELFTLAQKRQEAKEASGQEYDEEEEEAEEKRGEIKIKLIMKSREFGECKLV +AKPTTHVRKMIAYFRLQKEIPDDKEISVHVDGEKLDPESRVEDTELEDMDVVEVHIR +>A0A1D2A5P4|unreviewed|Ubiquitin-like domain-containing protein|taxID:3075 +MSDTGEDSKANIKPEGASDPNVLSIKVKDQLGGEVVFKVKKSTKFEKILNAFCQKKAVAISEVRFVFDGTRINPSMTPED +MEMEDGDTVDAFLEQTGGC +>A0A8T9BQC5|unreviewed|Ubiquitin-like domain-containing protein|taxID:1316785 +MSGSDENGSPGAAEKPEGAGQSEHLNIKVTDNNNEVFFKIKRTTALKKLMDAFCERQGKAPSSVRFLFDGSRVQPTDSPE +TLDMQDGDTLEVHQEQIGGAN +>A0A7L4GPF8|unreviewed|Small ubiquitin-related modifier|taxID:8905 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A0D2NJ78|unreviewed|Ubiquitin-like domain-containing protein|taxID:945553 +MSDEEQQHTQDAEPKIEDANATINIKVVSSAGEEVFFKIKRSTKLSKLQGAYASKVGKDVGSIRFLYDGARIQDDDTPSS +LDMEDNDTIDVMVEQVGGR +>A0A0D1ZNC1|unreviewed|RING-type domain-containing protein|taxID:91928 +MPKAIAGSVEDDWIQLTIKGNGRGVVTMDFDKNAKLSELMFSFWELTCQPPHPAAFLYKGIKLRARDTPMMLEMKDNDII +EYRRIRRHPRLIQVDDMLLLIEAGQQFVRKMDPIVEWERFNKDEVAEYRATIHSIQLYFSQAQASLKALVENEAFPLDGD +ATRVMRKRQAQLANVLIRLFRVHHLVYNKGYQAKVHPLPFRTGAKCLLAVENLAALASVVRNLQYPDVWERVPLSIPGLL +KENPEPVKPVEKRTGGRGVWTQEIPQLRQEQHGECLVCHEPCTSTTNTRRVFRKNGVATCTDCCGKAVHPRCLARWFAYE +RLSTDHGDTGTCPACRHVFPPQVAMLIMYMAIAHLGLALDASPKFRAWLARLPKQGAGSYLDVYRDHSHWFWKD +>A0A1I7UEL1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1561998 +MRHAMTEMYSLHHILLNQRFDWVNYQNDDWVHYQIVHLSGMKAQLVFLALVGLTAGLDFKPLLDLCSNPPPATRTLPQSK +MILPENYKISGSVTNMFAMQTWLLKETATKDFRVLERQTKEFQETWIQDLSGAHPLMFVNTSSGGCNGNATKPDIIGTER +FKIVLGSDTSSINSMANALLKYTTDVKGFLVENHIDLVGGVNANTWVARIDGKSSKYLLEVRYGGDDTVAPAVSTFFNPL +LLAFRIAELPTFNSTVAQNHWAGELDRYEKPVGNEAFIPHGVVCSHIEASSLRMKDVDEFAATLSYFDYKTNISEVVDVL +YSKSRRVFIVAGNSFNRILKFKDGSYTNGTDYVLHDFRYEGVEIRVQDARDNIGARTTGRQLKKGHNQMGHTQGALERAA +KPPLGWIWGDFFRPWQRMYPGDKLFNADINTRREYIPLSLVELARLIDLGWINPRAISKPIRFLSSETKMNMIFKYILLI +SSLIMILILLFRVEKICYNDTPVFFLPTFFSTWNSCVQRELTDKNTEEFWRNFKNKSRKCDRESEVLKSMGVVSLQNRDE +MKYAILPIQKMSKINENVSFYGADPIVEGNSKLYSKIGKYFPFAVGAKAGYSTASVLLDGEYKDVSVCHVDIYYFLKEVI +QEKVIDYLWMDAEYAEYGMFDLFYRNGPMETNGLTFCQMSLEVHNPSKEHKEQFKVFIKRLVEEKQYGFFFSEHVGHMRM +WLFNFRTMVWVCAIIVFAGVLLEFMKYMRWKIEKWQKNRDEVITRRFTLESISDWKHFTSSFLFFIQNFVDYSLMLIAMT +YNYPFFFSILGGHAIGYFLVGPLMTIEENPQTTMADDGAAAAAAPGADAAEYIKIKVVGQDSNEVHFRVKFGTSMAKLKK +SYADRTGVSVNSLRFLFDGRRINDEDTPKTLEMEDDDVIEVYQEQLGGSSI +>A0A3P8S4C1|unreviewed|Small ubiquitin-related modifier|taxID:161767 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKEV +NLSFLTLPTSVLIQRVFCVPVLLFIKPD +>A0A401P0Z9|unreviewed|Small ubiquitin-related modifier|taxID:75743 +MAEDKAKGENVKSEGNDHRNDHINLKVAGQDGSVVQFKIKKQTPLSKLMKAYCERQGLQIRQIRFRFDGQPINETDTPAM +LEMEDEDTIDVFQQQTGGSC +>A0A8C6ETX4|unreviewed|Ubiquitin-like domain-containing protein|taxID:9994 +MKAYCERQGFSMRQIRFQFDRQPINETDTPAQLEMEDEDTIDVFQQQTGGVY +>A0A922CHD7|unreviewed|Ubiquitin-like domain-containing protein|taxID:7130 +MSDEKKGESEHINLKVLGQDNAIVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEV +YQQQTGGVSLV +>A0A0C3F895|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:765440 +LSSEDEDNDNEALQSIDNTPNGKRAGKAAGKRKREPTRSRSITPPPPIALHQIQYARNLVRQTLDSGPRAPSPTWLTADD +SNDNITLDPELAKIAREIRTAPTTTAAWGEGTGGGPEVVTVKVKWQPHPLDDAARPGVWGFKMKRHDNFKQVFDETADSA +GVLSSNLIVSYEGKRLFSSATPHSIRIWAEAELEACDKTTYEYIRTHRHQRSLSPSRDHPGAGISGADGPSRSSTQDLSD +ASDAEPQDSQDSQTFKLILRSALTSKDITLTVRPTTTCGAIVKAFLKSAGLSDKYPGQGGMGGKVPMLCLDGEKLNPGSE +IGDAELEDGDLIEVVGL +>A0A8J4KY45|unreviewed|Small ubiquitin-related modifier|taxID:79626 +LFSQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A395HSF8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1450537 +MADSNASPSGGDAPAPVEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCDRQGKQPSTVRFLFDGTRVRPEDTPDTLEMA +DGDTLEVHQEQIGG +>A0AAJ8CUF4|unreviewed|NFATC2-interacting protein isoform X1|taxID:9994 +MAEPARRRGRRPRGGGVGRGARGARGGRGRRPRAQRSPARRTPDTVLVDLVSDSDEDFVEVATARGAAEPAEVSSPIVVP +SPEPPVPAAPRADSDSDSEGADARPAGAQRTLVRRRRRLLLDPGEAPVVPVYSGKVQSSLHLIPDHVSLLKLCPEGAEEE +ADVADASSPHSEDPPRPDSPWKKKLRSKDEKEEKKKKVFEARDTSPLPPPPPRTKSRKHTRALQKLREVNKRLQDLRSSL +SPKQHQGQGRQSQDDEVVIVEGPTLPENPRLFPLKIRCRADLIRLPIRMVNMSEPLQSVVDHMATRLRVSPSRILLLFGE +TELSPTATPRTLKLGVADIIDCVVLASSSEATETSQQLRLRVQGKEKHQMLEISLSQDSPLKTLMSHYEEAMGLSGHKLS +FFFDGTKLSGKELPADLGMESGDLIEVWG +>A0A9W2W373|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9691 +MGDEKPMEGVKTESNDYSNLKMVGQNASVGQFSIKMHISLSKIMEAYCEQQDLSMRQIRFQSDGQPINATDTPAQLDMED +EDTIMGSRI +>A0AAD9VJL0|unreviewed|Small ubiquitin-related modifier|taxID:1348599 +MSDEKKETKTESEHINLKVLGQDSAVVQFKIKKHTPLRKLMNAYCDRVGLAIAAVRFRFDGQPINELDTPTSLEMEEGDT +IEVYQQQTGGAC +>A0A8H4THM6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1208366 +MKKLPFKPTALRRAAPKPTQPEESKESDDDGLALFRRAKEMAPIMAADRERRLKRHRAAELETERRRHETGGDKRSREDS +EDMNHGTLGDQYSDVKSAELQSSPIRPSNEIPALDQPSTQDRADRNRFACQLYNSRSSADSPSELVTPPPSKRSRLSSSS +SQKPILSGQLDMDDDPYPDASPTRRLAPSIPTPSRAPKMEKPTPQATQPITIDSDSDSDSGAVATKPLATLPVKRRSSSI +ELIDRTSTKPSSKEPIPPPAEEDEFAEYIRKAEEERARQRALQEANSTGEQKKETIEIMVSSEIPNASALKMRYLFTKSL +RIAREAWIKHQWKKGLSLSADDVILTWRRKRVYNASTLISLGIRPAGDGRIEADGLGSVGFTDNRTVVHMEAWTPDLFQE +MERNEELRRKRDAGELSDDEDEGPLEDERFKVVLKGRDMEPFSCTVRPRTTAETIITCFRQQRQIGSDKEVSLWWDGERL +EEHIEMEQAEIEDMDTIEVHIQ +>A0A7L3Q6D0|unreviewed|Ubiquitin-like domain-containing protein|taxID:68486 +ILQFSVQEGVKTENEHMDLRVAGRDGSVVQFRIKRHTPLGRLLKADCCRRGLSMRHIMFLFDGQPVKENHTPAQLEMEHE +DRIEVYEQQTGGGC +>A0A3P9BKZ5|unreviewed|Small ubiquitin-related modifier|taxID:106582 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGVC +>A0A813U3M6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:433720 +MEDDEDDFFAYQTAKSLNNKRTQLKQFYQTSITSKQLSSSNSSDSDSENDLISITKNKKSKPISTINHKSIEPIVIQSEP +IKTKDSIRNEIDAIVTSCFTTTTNKEVKRKIKLGKRTAADDQQYEDEDEYLTHINQNRRGGYMNRAVINAFNKSQLEEDD +EKVTRETAAYNRLDAVLRVTKPLCERQIDSNEEDDEDEEVDEQIKTDLLNDSDIINSDKITLKIDHSDGRQLTLLLPLST +TLKTLYDQVAEGLCLPSIYLVYNDKTLKLDDQNQSLTLKQLDFSSNNVQLLESYPLIRKLKIFIQTSTSSSNRRSSLSKR +EYSMLDTDHFEIIFNAYKNDMKSTNIRFEFDGDTLNPRATPNDYDMVDGEILDAFISLPTSKNNNNNNSNNNKQNIQSKT +RKTKEILYNDDSDN +>A0A8T2ZKQ0|unreviewed|Ubiquitin-like domain-containing protein|taxID:3696 +MSGATGQPQEEDKKPNDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRGEQTPDEL +DMEDGDEIDAMLHQTGGAVNTTLTKSFDSNCTILLGLDLQCLVCWDMAPHSSCSLPPYFSMCYLSQRLRALNVLSDLLEC +IGNRGNCIQWEESGVRKAILHPSKYHGQAVIPTGGLVRDGRPVLLPAWKLKVLTQRCACDFRIPKVWDLSARTSSQSNLL +CCAYKHSSTSKE +>A0A540NN29|unreviewed|Small ubiquitin-related modifier|taxID:106549 +MSATGGGGSGSGGGGEAQKKPLDQSAHINLKVKGQDGNEVYFRIKHTTQLKKLMTAYCDRQSVDMNSIAFLFDGRRLRPE +QTPEELEMEDGDEIDAMLHQTGG +>A0A066V7H9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1287689 +MQYNKASQARSKLENLARELQKDNKKLREDTRRLTISFEEARDEINQVKDELVQRQMPHPRFFAQSGIDLSARKPLVNGA +QQQPADIVVKVVCKFREELFFKINRKTKLTRLFSTWESRMDTNSSDKKSGRTHFIFTHAGRTIDWESTPDQAAIENNDVI +MAVELMDLTQAEPDDSTVTKPKITKHVPEDENEAARAVEEMLDVVVRERLKDVLRQYERRERHFEAVVRSKELEVLLARA +RVEEQKGCVESARRAARALEQQNAAYQTELEDLQRQEAATATKIQQCLLTLGKNPAADPTPAAARIVRDVLREHLDLRAQ +AIDQVTNGHTSGEDS +>I0FUF6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9544 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>X0BQI8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1089452 +MSNENENGTPGEQAPANSEHLNIKVTDNNNEVFFKIKRTTKLEKLMGAFCERQGKATSSVRFLFDGTRVQPTDTPDALEM +QDGDTLEVHQEQVGGSAQ +>A0A2K6BV86|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9545 +MPQIIYNFKTENNDHIKLKVAGQDGSVVQFKIKRHTPLSKLTKAYCERQGLFRFDRQPINGTDTPAQLEMEDEDATDVFQ +QQAGGVY +>A0AAD8YHV1|unreviewed|Ubiquitin-like domain-containing protein|taxID:267567 +MGDVFDRYAARKEVNPDRLIFTRNGEIIDANQTVADLGLDANDLIDCVYDPETINIRFNSHDGPEITINIRRTDRISLAF +DEYSSRSGIAEHNMLRFEFNGDEVHPDSTPENLWMNDNDMIHCSFGPLYNGNANGANEANGANGANEANEANEANEANEA +NEANEANEANEANEANEANEANEANEANEANDANDANGANEANESIVIFIKNQCGEVIRFRVRRSTRMMTIFRTYARRKG +MRAQSFRFMTNGEVIDPALTLARLGLADGDMIDCVLNLCGC +>A0A7L4LG81|unreviewed|Small ubiquitin-related modifier|taxID:1347786 +PPQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGVY +>A0A6G1IAJ3|unreviewed|Ubiquitin-like domain-containing protein|taxID:703511 +MSDHGSPNQQKDESQPEHLNIKVTDSNNEVFFKIKRTTALKKLMDAFCDRQGKSPQSVRFLFDGQRVNPTDSPESLEMQD +GDTLEVHQEQVGGGC +>A0A540LQP2|unreviewed|Ubiquitin-like domain-containing protein|taxID:106549 +MTNNEDPQSQSTKKTRELPNLSECHCCHLRVDIANASAKSKLHILYSEWRVVLLCKKCLSRVESSEFCSYCFAATSPSQS +QEDSFTCCQCNRRVHRHCDSEYRGIALLSQDSCLAVEVGVCADCWLPESLARWRGVMRSQKARRGGKGRACLGLGKYRVS +AVLDGRTICDVSGAEEGSKDAAFDVDVDDDDDDDSGHLAAMNSSAKKLCSPNLSVCVCDSSTGVGCLKLDIEEENEDDDG +LLIEGQGSNSNGVDALNKQELDECVCVTMPKDKRRNSKLDPFYFKYRKRSMVNQSVNTCLNFVGMDDHVPAITSEPLVRL +SPEKDGDPMILLKVQSQQGSVISYMTGLHMHLKHVTRDYCRRLNVSFEVTRFLYDGRRVKQTDTPAKLEMEEDDAIDAMV +DMIGGGGGY +>A0A2K5MG27|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9531 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQLGMEEEDVIEVYQEQTGGHSTV +>A0A3N2PMD4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314773 +MSAAPKRRLPFKPTALQRLSAPTPESKDKDGDAEDDGLSLFQRSKEFFPVALAEQERRRKRKHSKRESSRNDRSSSTAEV +KDGVDKVKVEDEESPLPRPTSRNQSQSQSQSQGQNSQPTVAVESTDDNDGDGLGATIATPPSKRSRTSHGSINSNPLHPT +SPCHARHPKSPARSRRSVSTRSPSKLQDKGKQPEFVDLEDESYHGQGASLDDPDEDIYGATPIRYVKSTRSSSAAHDLED +PFVVEEEEDKKDDALREEEEEDDDDEVNGEFAEFIRAAQERQKKAEEAEKDKTRIQLLVTSRLPDTEPKRFVITLWKPLS +AVRRAWCLSTGATLRLGRQTLEGTFLTWRGRRLYDSTTIDSLDIRASASGTLQHASVGKFHDTDGFSKDWTRLHMEIWTE +ELWEEHQKRMERERRRALGELYDDSDDGGAALDGENDGEGAPAPAPEEQKIRVILKTRSDEPVKTTVRPSTTIQTLVVMY +RKMRNVPEGSSVSLYFDGEQLDEASTIEEVDIEDMDTIEVSVKD +>J6EUK3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1186058 +MSEHGSPPADVKPKADGGENALNIKIRATDGSEVFFKIKKTTKLNKLKVHTTIMSDVLMSQNAYADRVGQDPGAIRLLFD +GERIADHQTAEDLELEDGDVIEVLLEQIGGSL +>A0A6C1DQK5|unreviewed|Ubiquitin-like domain-containing protein|taxID:27292 +MTGDSRSISEPSINLDPDNTSFSDENSDDFFMDNSYDIDEIDHSDESNRQSVIVDSKVTVPPSKHSTLTLSDSEDSDAKE +QHQSLSRSSSKNVNIEDITEPKPDKPSGRTRKRSVMKESVVEINSSESDLDGDKNLPRSRSRSRSSIRSISPAGKYKRQK +SSLLYTYDENDDFFKELAKEAKKSTTISKESTPDQRKRVYNIKFLSKLEGTINKAVQVKVLGKYEFSKILPAALDGLMKS +YKIPKVMKDIYKVENVTLYWNNAKLLTFMTCNSLHIPQDFENEVSDIDVTIVSKEYEKNFEATLESKLKEEEAALLIKER +QEMERKLEKKRNEQEESEYREFESELKNVEETQEIKENDTVMNTKLLQEGGSLSGNSSSMEEVMRIALMGQDNKKIYVHV +RRSTPFSKIAEYYRIQKQLPQKTRVKLLFDHDELDMNECIADQDMEDEDMVDVIID +>A0A1Q5KCK4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1703943 +MSGEGDGTIQISVRSEDGHEVHFRVRSTTQMQKVMRAYCERVGSSLDAVRFLFDGERVRGYQTVGVLALVSGDTIDAMVE +QVGA +>A0A1G4JRC1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1230905 +MVDEQSHAQLKGAVITSNIEDQLSYSDANKTVGGYIEDEAPEAGEVGPEREKLPRFSSTIKVVARTDTQETLKDDKETSE +AQLDDLDDFFYGDYLLGGKSVSQEKGVVEDSEIPRLDVKQVRRFKREDKPRESETGDVATNTRTTRRRRVSHASSSSQSS +EISQLSSRSSSEERSAPLPLEKRPKVIAAQVPDRTDTIIISDELQTTQERPARRSVDPSAGTRTPEAEGIAAYPIKFVSQ +LEGSQGKAVEIKVQGGHSFSSILPTALSTLTEEYPIPPELQHIYAADRVTLFYGNGVKVLGFMKCSSFRQAENEENDNQD +IEIYMVSTDKAREYERNYAVLRQQELESLSATPEVLVDFTKQRGPLRIEESDVEGSDDSLQIIEPSEDEARVLRIALMGQ +DNKKFYVNARERTTFAKLADYYRSANRIPSSKNLTLTFDSEKVDLNCSVDDLDLEDDDILEVVVT +>A0A7J6VJ11|unreviewed|Small ubiquitin-related modifier|taxID:46969 +MSEADGDRINLKIKDQNGKEIFFRIRRTTELRRVINAYCDRQAMDSKVVRFFYDNQRIRGSETPDELDMEDDAEIDAMME +QTGG +>A0A1J4MYW6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:117008 +MTLPQFPISGLEQWRVHIQNSITSDAVKNGYTKLNILDSFNFEKLSLESNEMCQHSVMYTSCDIRELAMQCSDENNEYIV +MILKLIFHKFLELLKISNDLPDFLSSSNSSKSKEWIRCRTVHVNCHSLPLSTPGDWLNCDDIEHMTHNNADPLYFHDMFY +ICIPIRLKHSCTHEDQSRESINIVAQKEMAILLTKQFADLYNQIINMKLKEDEYLPLNIDNWAKYYPANSLRVGLFTTLK +VSTLHLYRLNPTIFTSPLFIHPLKLNNCSSCSYAWLRKKKFKTDTLLKIKKQKLNENITSTNNNLNTVEAHILALETKNL +VFLNGPEVNRNNIIIHRAIRTRINGISTNNQQPQYVGEIGWPGKTANETIDSKYLIGFSNLDSVVVGVLEADKKSSSPNI +DNTSTIENWNQGGEIALKFKGKDLEIVGMMIDDYIIQEKYIDNSDDDTTEGPTILIRLCSKYSVIPYFGLRSLLRFHDSL +VYNSSALGIASNNQSKQMNISVHLLCCICKFLTIREFAMFRSICRSHCNRIIFNSYIHEIALEEKDLYLPILGQLYPYLS +KAKSVRVLQSQTSSFDNMQLIPPIVIQCLAAYTPRAKKMIFSNHSPANLAKIVSRACGRKPEMIVLTKNVNIVNEDGEEE +DEERLNRINLIDNVTQEERISRTDQEESTGNSDLVDRNDNINNENIENNVTNNSGNLFDNNEGENNLYNPNTHGTQSEVV +SQQLSMPTVPQPSPATTPNIQPHIAELSLPNLIEIHIIGIIESISIIPTSIFRIPATAPFRKLVRYFRDVVSIHEGIVDF +YIVRYGIKDRLIPDLTPIDYGILRGPAVLHAIGYKTLQYSQKIWISLFLVGSRNFPYLAKLRFNASMSTPFSRLADSYSR +NVNIAVSDVIFYYKDVEIDLSLSPFDYNVRENDTIEVSLRGRSGCQ +>A0A6P3XVL7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:609295 +MNQIVIDSSDEDDTYTSSVARLRALKRKRFEDEQLVKSTSIVVTNGKDDNITSTSCEVVPHVIPDDSIIEKKTAMTRSRT +RKKGKSRDNGRYTKYPATTTRSTRRRPFINNLDCNVEFVSLEVNPNSVSKCNKNDTVTFSSNNTIALSSDDDANGEDDNY +EITVKVLWRSIRLDRLSMRRHDSFLKIFQHYADLEKVSVNEVLIMRNDKIISFDDTPALLKLSVVDILDGGIVNPGMRPN +TDKDANENDAYNIKVQTANKKQSLTFPLKKNEQFQALFSYCASHFGEKEGRLKFYFDGEQINPTDTPESLDIEGEACIDL +QISSG +>A0A6I9W3M7|unreviewed|Small ubiquitin-related modifier|taxID:144034 +MSDENKETKTESEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRVGLAIAAVRFRFDGQPINELDTPTTLEMEEGDT +IEVYQQQTGGFSC +>A0A9B0T364|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:185453 +MADEKPKEGAKTENNDHINLKVAGQDGSVAPFKIKRHTPLSKLTKAYCERQDTPAQLEMKAEDTIGVFQQQTGSVF +>A0A4W2H380|unreviewed|Small ubiquitin-related modifier|taxID:30522 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRHIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A0J9U5R3|unreviewed|Ubiquitin-like domain-containing protein|taxID:7240 +MANQSKTIWLLSSNLPKLRCHVRTDQPLAALLRQKYAKAFGVATETLILAFDGEKIQEEDTFDSLAMEDNDIIDVVDEC +>C1MTL0|unreviewed|Small ubiquitin-related modifier|taxID:564608 +MAEEEKKNDEKGDHINLKVKDQDNSEVHFKVRQTTKFSKIFDAFCARKSLQPDSVRFLFDGQRVNANMTPKDLDMEDGDS +LDAMMEQVGGF +>A0A834K6I6|unreviewed|Small ubiquitin-related modifier|taxID:30213 +MSENQEQKPEAGPGDANSEYIKLKVVGNDSNEIHFRVKMTTQMGKLKKSYSDRVGVPMTSLRFLFDGKRINDDETPKQLE +MENDDVIEVYQEQTGGLY +>A0A8D3C6E7|unreviewed|Small ubiquitin-related modifier|taxID:52904 +AADEGLEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDED +TIDVFQQQTGGRC +>A0A225ZPX9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1230068 +MSERASNPPEEKPKAEEAAADPNTLNIKITNTNNEEVFFKIKRTTKLNKLKSAYADRVGTDVASIRLLFDGHRILDHQTA +NDLDLEDGDAIEVQLEQVGGY +>A0A7J6CXA0|unreviewed|Small ubiquitin-related modifier|taxID:369639 +MSEDKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSC +>A0A199VU30|unreviewed|Small ubiquitin-related modifier|taxID:4615 +MSGAGQEEDKKPADQSAHINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEME +DGDEIDAMLHQTGGTSASA +>A0A8H7MAZ8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:45133 +MADGAAPPKPKRSFFKKPSWKQNADTGDDDDPTAMFDGSKQTFSAIMEERERARVKKLQEQEESARKRELDAARRGKRRK +TAHDEEHPPVRRDEGQSELARQHASLSSSPPPLPTVDAHSLSARYEADARASRARDAELRPAVVVDLGDTDSDDNAPPPA +ERVPEQAAPTDLDEEIDESDPEIREIIRETRRKQKLAREQDATRGASPVGAGNRHKQSPAAATNCAPDPPVQIFITSRIP +NTRPLIVTRKLSQRLQEVRQAWCKRQGFDQKMTDSVFFTFKGRRLFDVATCRSLGLVADAFGGVRMKDGFDWDENDGKVT +IEAVTLAIFNEDAKEAQRQREPEPEPEVAPEPEQKRTKIIVRTKDFGDAKFTCGPETTFEKLAMSSINRLKVPAGKRPYL +LFDGERLDPGGTMAELEDFEDEDALEMHFE +>A0A5F9D1A0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9986 +VPGCAHLPVTVPGCSHSPSPPWGAPPPCHSPRVLPVPVTAPGCSPSPSRSRGAPPLPLGPRVHPSPSQPQGAPPLPLGPR +VLPSSRPGVGPFLSRPEGCPGSGRQSLGRWRRKLRSLSTCWGPGAPCWGPGAPAAAGVRGEQPPSQEGVKTENDHINLKV +AGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMDDEDTIDVFQQQTGGVSSRLPGRGLFSILAFAVE +>A0A9P6GPY0|unreviewed|Ubiquitin-like domain-containing protein|taxID:565426 +MSDNGSPMQQKPEDGQQEHLNIKVTDNNNEVFFKIKRTTQLSKLMNAFCDRQGKNMQSVRFLFDGQRVQPGDSPDTLDMQ +DGDTLEVHQEQIGGC +>A0A9N9Z2R1|unreviewed|Ubiquitin-like domain-containing protein|taxID:160281 +MSAEHENGTPAAPSAEHLNIKVSDNNNEIFFKIKRTTKLEKLMTAFCERQGKSISSVRFLFEGTRVQPSDTPEALEMTDG +DQLDVHQEQVGGW +>A0A6P5QQ94|unreviewed|Small ubiquitin-related modifier|taxID:10089 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSASRGSVPTPNRCPDLCY +>A0A8S1PYW3|unreviewed|Ubiquitin-like domain-containing protein|taxID:5886 +MHQFSIPIEDIMDLPPIADEINLQLGEKIDTKIFQQNKVVQNQITQNQQQQPLQNPQDEEMLNTKHKEINQFLQSQQKEQ +LSQNFSFGEINLMVKCLQRNKTFSITVPPDQLVEELMMEFQGILQTQNKMQFYFQKKPLDGNCSFAKYGIGNGSVIEMSE +IICCGCFPFYAPITLADKSQKPISEIIKGDQILCYDYEQREFRPGIVQGTTKTKYKIQLIRIETETRIIDCTADHPFYTQ +SGWKAFEPHPDFQISNLALEDKLLFEDNTFINIISIQKLNQFDYVYNLHLKYPNNYLVFGFLAHNMNIIYVKIDGKYKEI +EYFPDMPIQQIKVLIFKKMGIPIENQKLYYQDILMEDEKTVKDYNLNYESEKQMKVLLDVSIDKEKQQYQSTHITSNSNL +ISVDIITNESSYNLLLYKHIELKYLQKIIRQFEDKNEKKLILIDGQSYKSEFYDMRIDELPKIQEILLL +>A0A340X4W1|unreviewed|Small ubiquitin-related modifier|taxID:118797 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEV +GMEEDDVIEVYQEQTGGRSTI +>A0AAE1K7N0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:499986 +MSKQEAATPEIDSEEMEEGKKMEKAGGGGGGGETAKEYVLSCGDKVFVTEMNVVCLIGPVTREERILVTVKYLGEEDLHY +TIGKSVKLGFLIEDYCDRKHYAKSNFQFTHQKTGKQVAENRTPEEFGMRHGDVILASLKPEVLQELEGKETG +>A0A167X3P6|unreviewed|Ubiquitin-like domain-containing protein|taxID:436010 +MSDEEHQAPPLATQDDVKPEADPNTINIKVVSSTGEEVFFKIKRNTKLSKLQGAYAGKVGKDVGSIRFLYDGARIGEEET +PASLEMEDNDTIDVMVEQVGGSTVAS +>A0A0L0S8V0|unreviewed|Ubiquitin-like domain-containing protein|taxID:578462 +MSDMKSASPAPGPAAGGPTQITLKLRDLDSDPGDDLEVRMRSSTKFIRLARTFATRQNRELSELRFMFKGRRILPTSEAP +VGDLGMVDGDTIEVSPKVMIGG +>A0A9W9NQ78|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:63820 +MQSFFNKPSWATVDGGTGNEFYRRSKQTYSDIIAANQEARKVQQKEEKESESHSIVFVEETARSKRPRLSEEIKRVNPET +ETKVHTDSDGLSNDQNEIMDSDQPTPHHSEWPASARRNDHDCYAAPADTPVPCNHHTPSDQIGHPSLRKPTTRHPWSGST +LSGGEQRSISEKPQSHPVQSPVSQKLSSALPSNSELVVRILVTSDIPNTKPFIFSRKLSQGLRQVRLEWCKRQGLTDEAT +AAIYLTWRGRRLFDVTTCRSLGIQNEKSRVSQATEDDMSEEQKELRIHMEAVTDDPSLLGCQYSLPIDAGRWSSPPPHSD +AGLQKDEGNKPLKIVLRSPGLNDLRIKARPKTPVSKLISAFREKHSIGADYQVSLSFDGDRLEPHTCLEENDIADLDMVE +VQLKPQT +>A0A3Q3IAA0|unreviewed|SGF29 C-terminal domain-containing protein|taxID:43700 +MSADTKIAELLTELHQLIKQTQEERSRSEHNLLNIQKTHERMQTENKTSPYYRTKLRGLYTTAKADAEAECSILRHALDK +IAEIKSLLEERRIAAKMAGVYSDSDPPRKTMRRGVLMTLLQQSAMTLPLWIGKPGESPPPLCGATPASSDYVAKQGDKVA +ARVKAVDGDEQWILAEVVSYNHSTNKYEVDDIDEEGKERHTLSRRRIIPLPQWKANPETDPEALFSKDQLVLALYPQTTC +FYRALIHTPPHRVSANEAQAVKLQPKRRRILDPSAIVPVPVYSNKVNSSLQLKPTAAIFAKKETTDDGADDGLLSEFSSQ +QTAAADITLSDSEEDEAVCVENKQEHKKVEATRCLSPSPPESPVQKQSRHVKKKLNEIDREFRAMSSIISPESRDRTRSR +QRQGPPSPTFEEEQNDKDVIIVDPNSASQRLPYSTSVREIPLKIRCRTDVHKIPVLSSTPLRDVVTQLSAILNVPPSRLL +LLREDVELPKDSTMSEIGLGIADIIECVVMAAEDKSETKESSSSVITVRLQGKDRNSSQEFSLHRNAPLGPIFSQYLSKM +PASAQRKVRFLFDGFKVTHSQTPAQLDMEDGDIIEVWI +>M3WR50|unreviewed|Small ubiquitin-related modifier|taxID:9685 +MSDQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTI +>A0A5D3ATY4|unreviewed|Ubiquitin-like domain-containing protein|taxID:2591691 +MNNVDPNTLNIKIVSTNGEEVFFKIKKTTKLNKLKTAYADRVGTDAGSIRLIFDGARILDHQTAADLDLEDGDSLDVVLQ +QVGGC +>A0A1A7YGB5|unreviewed|Small ubiquitin-related modifier|taxID:60296 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGCC +>A0A401QM66|unreviewed|Small ubiquitin-related modifier|taxID:75743 +MSSSREEAKPSSQSGEKKDGEYIKLKVIGQDNSEIHFKVKMTTQLRKLKESYCQRQGVPPNSLRFLFEGQRITDHQTPKE +LGMEDEDVVEVYQNRQEDG +>A0A1P8BAF0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3702 +MSNPQDDKPIDQEQEAHVILKVKSQDGDEVLFKNKKSAPLKKLMYVYCDRRGLKLDAFAFIFNGARIGGLETPDEANHSL +FHFPFTIYMFVKSVSFTKPRFSNFKA +>A0A7J6WP13|unreviewed|Small ubiquitin-related modifier|taxID:46969 +MSGIPNSEQEETKPNAEQLLHINLKVKDQNQNEVFFRIKRNTQLKKLMNAYCERQSVDPSTIVFLFDGRRLKETQTPDEL +EMEDGDEIDAMLHQTGGFTI +>A0A540MXL8|unreviewed|Small ubiquitin-related modifier|taxID:106549 +MSDPSGITPDEAKEQKPTINLKVKINKDGSEVFFRIKPTTKLNKVIDALCTKRSLDRNSLVFIFDGDHINGKKTAAEHHM +EDGDEIDVFLLTDGGSLTFNSY +>A0A817WIX0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:392032 +MEDDEDDFFAYQTAKSLNNKRTQLKQFFQAPVTSRQSSSSSNTDSDSEHDLISTKKNKSTFVTIPIQSILIQTETIEKKD +LIKNEIDAIVTSCFTSKNKEVKRKIKLGKRTLADDQEYEDEDEYLMDVAQQNKNVPISRAKMNSLNKSKLDDDDEKVTRE +TAAYTRLDAVLRVTKPLCEKQIQSVDDDDYEDYEPIKITTSSSTDTIEPVSPVKSSLLKTITLIIDHSDGRQLNLSVPSS +ITLKSLSEDVAERLSLPSIYLVYNNQTLKLDDNNQSMTLQQLNFSSNDTQLESYPLVRKMNIFIQTSATSARRSSLVSKR +EYTILDTDRFEIIFDAYKRDMKTNNIRFEFDGDTLHPHATPVDYDITGGEILDAFILPTSNNNNNKQKNELKAKKTKEII +FDNDSDD +>A0A9P8FFD1|unreviewed|Ubiquitin-like domain-containing protein|taxID:46634 +MEGTEQPPTWPPCPTVEDESASGNQADATSTTKRNMSDLPNGPSAAADGTNARMATPSTPVNNGAETTAQNPEEPRTPAN +AAPADPAVDRVQIVLKDQSGTQIAFGVKSNTRMEKVQNAYADRTGRPVGTLRFYYEGTRVVPEDTVATLEMENEDIIEVM +TEQIGGEGSETENNTPGKVTIVVQECEIDGKTCPAACFRMSSRSEFRKLMTTWTELRGGKVAVGFYHEKQCLGDKAETRV +RETDTPEKLGMGVNVILKVIQDSEMTNTIDVDDDWVEMDSVSVKNEAPEKSFVLIVKYLEQDDISREMHCKMTQSMSFKK +FIDLYAKRWDIDASAQRLTFNRETVFLSDTPASIGAEHGAVLNIAEDPNVFTMDLTLV +>A0A6P6UYZ1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:13443 +MADSMEELEPLFDYRRVQPFNVVIVDDDPLDAPPVGCKKKRKTADSAVEENDNKGKVVQVIDCDENEEEEEEEEEDWLPP +PPKMTNDTSKLNEDSTIKELRLKRQELASLAQSAKDALKAVEESVRQEFAAAESMKSHLNASSQSPTRGIAEQPSDTCQD +RAKIVITIQDKDGPKQFRVFMDDKFERLFKMYAEKVKLDLQNLVFCFDGDKISPTATPAGLEMEENDIIEVYVKRK +>A0A2K6MT35|unreviewed|NFATC2-interacting protein|taxID:61621 +MRKSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVLASSPEATETSQQLQLRVQGKEKHQ +TLEVSLSRDSPLKTLMSRYEEAMGLSGRKLSFFFDGTKLSGRELPADLGMESGDLIEVWG +>A0A6P9DII9|unreviewed|Ubiquitin-like domain-containing protein|taxID:94885 +MSCLASLLEAQACRESAGGLSPQRGFRAAAAALGAFKKRRVGLLKGKPSSLPVLGPRMSVPRPGCERETGPASPGRRALP +RGGSPTLFLPRAPAGIEREGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINET +DTPAQLEMEDEDTIDVFQQQTGGIC +>A0A6J5XC52|unreviewed|Small ubiquitin-related modifier|taxID:36596 +MSGVTNQEEDKKPTDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRAEQTPDELEM +EDGDEIDAMLHQTGGAFA +>A0A3D8QX36|unreviewed|Ubiquitin-like domain-containing protein|taxID:1849047 +MSASDENGSPGAGDKTEQAPSEHLNIKVTDNNNEVFFKIKRTTNLKKLMDAFCERQGKAPNSVRFLFDGSRVQPTDSPDT +LDMQDGDTLEVHQEQIGGG +>A0AA39RXZ4|unreviewed|Ubiquitin-like domain-containing protein|taxID:4024 +MSATGGGGGGGQEEDKKPMDQGAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVELNSIAFLFDGRRLRAEQTP +DELEMEDGDEIDAMLHQTGGGLEIHKGAAQTDSLARSRLKGKEKVGEPSEPIALYHGTSSSRSVVNEPDNAPRDAETVRE +PLGAVALKILIPPESVVVPFSAGGGAELRHPDLDSEDSAADLNTCGR +>A0A4W5KXV1|unreviewed|Ubiquitin-like domain-containing protein|taxID:62062 +MFVFSQILPNIRSKPTDNRQMKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQVIVRFDGQPINETDTPAQ +LEMEDEDTIDVFQQQTGGLY +>A0AAD9ZP88|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:43782 +MKPTALGLIDIMVKNDWVGMQNGDVIDCMITDSSIETLNMSQQEEKPNTTPNPIINVMLYNKLNGMMVFFKIKRTLQFHI +LVKAFCERTSVDANHARFLFDDRQLVLDQTPQQVY +>A0AAD4JLG1|unreviewed|Small ubiquitin-related modifier|taxID:608512 +MSSVEDDKKPADSSGHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDG +DEIDAMLHQTGGAAA +>A0A9R1CZ50|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2011032 +MPDSDSDSSTDFFISKRKPNLKASTPPPIHSPSPAPSDSDEGPESSGRKKKKRLNSRKPQSKLPEWARQTSEQRKERKRS +SVARASTETRDREGSNSSQVYHILNAGLCRRMYGGGSALDLLDDDDVEPQPISPMVSPQKEEVVDIVVKMELDPVKKANA +PAVAIRMYERPTTLKLRREETMFRALEVMGDKLQRAPEDIVLIYEGKRVYSRDTARQLGILGGSSAEMKGYEKSYWDRLE +AERLRRIENFDLDYSNRSPSPQPILQAQAHAQVSTAFKSKAQSQSQSQSQSHGASQLYAGLAPLVVEPPNPSHVNNSPPA +VADDSIKFVVRGADGKEARMKVAKTVTAHTVLRFYCKKTNRPKDDANKMELVFDGETMGKDATVGDMDCEDGDMLEVRIH +>A0A177EYJ3|unreviewed|Ubiquitin-like domain-containing protein|taxID:254056 +MSDAGQGGSPNGAAGDAPPAGVTNNEHLNIKVTDGNNEVFFKIKRSTKLEKLMRAFCERQGKDPKAARFLFDGQKVQAGD +TPEQLEMQDGDSIEVHQEQIGGRA +>A0A9J5XL08|unreviewed|Ubiquitin-like domain-containing protein|taxID:4109 +MSENKIPIGEEATKFDIHVLSQDESIIILRMSPNMIMEKLFKSYCKKKQIIDYKTIQFLFDGQHISPKMIIHELGLKDGD +QIDAMLHQTGGGFTN +>A0A9P8AJF6|unreviewed|Ubiquitin-like domain-containing protein|taxID:45513 +MSEYEQQGETPKEQKETQAHINLKVSDGSAEIFFKIKRATPMKKLMEAFCKRQGKPMDTLRFLVDGTRISPENTPDDLQL +EDGDVIEAHREQIGGSY +>A0A2P6VFB4|unreviewed|Small ubiquitin-related modifier|taxID:554055 +MEDSGENNIKKEAGGGEAMSIKVKDQSGGEVVFRVKPHTKFEKIILAFCQKKSVDPAQVRFVYDGNRLDRNSTPAELDME +EGDTIDAFLEQIGGCC +>A0A8D2GN97|unreviewed|Small ubiquitin-related modifier 1|taxID:9565 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKET +QWPTPAILALWEAEAGWITAGQELRPAWATWRNPISTKNRKSSRLGMEEEDVIEVYQEQTGGHSTV +>C1C2M5|unreviewed|Small ubiquitin-related modifier|taxID:344056 +MSGENKDETEYIKLKVVGQDSNEIHFRVKMSTQMGKLKKSYSERVGVPLSSLRFLFDGRRINDDETPKALEMEQDDVIEV +YQEQSGGNHHDPNTTTTTSTSTTSTDL +>A0A480RVR8|unreviewed|NFATC2-interacting protein|taxID:9823 +MAEPLRKRGRRSRGGGVGRGTRGSRGGRGRRPQSQRSPARRTLDPELVDLVSDSDEDVLEVATARGAADPAEVPLPETPV +PAAPRDDSDSDSEGADAGPAGAPPILIRRRRRLLLDPGEAPAVPVYSEKVKSSLHLIPDHVSLLKFCPPETEEEAESVDV +ADASSPHAEDSPCPASPWKRKLRSMDGEEKKKVLLVQDASPVTPPPPRTKSRKHSRALQKLREVNKRLQDLRSCLSPKQP +QGQDHLSQEDEVVLVEGPPLPENPRLLPLKIRCRADLVRLPVRMSEPLQSVVDHMATRLGVSPSRILLLFGETELSPTAT +PRTLKLGVADIIDCVVLASSPEAAGTSQLIQLRVQGKEKHQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLTFFFDGTKL +SGKELPADLGMESGDLIEVWG +>A0A2K6Q9M8|unreviewed|NFATC2-interacting protein|taxID:61622 +MAEPVGKRGRLSRGSGTGRGGRSGWGGRGRRPRAQRSPSRSTLDVVSVDLVSDSDEEIVEVTSARCAADEVEVAPSESPG +PVASRDDSDSDSEGADARPAGPPREPVRRRRRLVLDPGEAPLVPVYSGKVKSSLCLIPDDLSLLKLYPPGDEEEVELADS +SGLYQEGSPSPGSPWKTKLRTKDKEEKKKTEFLEVNKRLQDLRSCLSPKLPQGQEQQGQEDEVVLVEGPTLPETPRLFPL +KIRCRADLVRLPLRMSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVLASSPEATETSQQ +LQLRVQGKEKHQTLEVSLSRDSPLKTLMSRYEEAMGLSGRKLSFFFDGTKLSGRELPADLGMESGDLIEVWG +>A0A835M2I9|unreviewed|Ubiquitin-like domain-containing protein|taxID:261450 +MSAGTGTGGGGAAPASQQDEDKKPNDQSGAAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVEFNSIAFLFDGR +RLRGEQTPDELEMEDGDEIDAMLHQTGGALDVNVVSFSASLGSFVSLLSIKGITMACLMCLGSRSNPATKVYHVCLGTLS +EAQSTSEAHLICLVYEQQGHYVDAKEFDP +>A0A7J6IR63|unreviewed|Ubiquitin-like domain-containing protein|taxID:1213859 +MEPKQESARDGNEQPPPPGPSGANGLSASFTSFLPSTPRHRPTLIALYVPPHAPAPQAPAPEDAAPHGAAETPNNAAINV +KIVDTTGHTIVFKIKRDTRMQKVMVAFCERQGKDPKSVRFIFDGTRLVEDDTPRSLDLEEDDVIEAQQEKIGGAMY +>A0A4X1UJ45|unreviewed|NFATC2-interacting protein|taxID:9823 +MAEPLRKRGRRSRGGGVGRGTRGSRGGRGRRPQSQRSPARRTLDPELVDLVSDSDEDVLEVATARGAADPAEVPLPETPV +PAAPRDDSDSDSEGADAGPAGAPPILIRRRRRLLLDPGEAPAVPVYSEKVKSSLHLIPDHVSLLKFCPPETEEEAESVDV +ADASSPHNEDSPCPASPWKRKLRSMDGEEKKKVLLVQDTSPVTPPPPRTKSRKHSRALQKLREVNKRLQDLRSCLSPKQP +QGQDHLSQEDEVVLVEGPPLPENPRLLPLKIRCRADLVRLPVRMSEPLQSVVDHMATRLGVSPSRILLLFGETELSPTAT +PRTLKLGVADIIDCVVLASSPEAAGTSQLIQLRVQGKEKHQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLTFFFDGTKL +SGKELPADLGMESGDLIEVWG +>A0A9P9YW49|unreviewed|Ubiquitin-like domain-containing protein|taxID:103775 +MSLPSAHAHAASPVYSNSNSNTNNKSSAGKQKTSSKNDLLRCAVGLLLKQKNYVSNEKFRRSDFLLLQNKQQFAVNKMLD +TDLHGGNSFTYSNVQVINNNQHTVDQQFGRFSQFVEAQAEPLRLEMKRFYGPMLGAVELLRKYAHLVAPVDLYDAPPPTK +INGCSTSATDSTFHIRFAREALDTGDTELDYFMRLVQTLSGYTRLEAAESDDTYELHTTAQVVERICTYLQRRGHVLIMN +LLYTWLHVHIVENEQRSFSEDHLLGLTDDLEGEEAEEEVLTKPISNRKRPAEEPNIKLEIDIKQEIDADESAEPIQSQLN +ISACLDTLKTATEQILKAQVELPRFIRISERSRGLTSAHMDTTGFDNSAVQLWQLNQSSCRGRSFYRRYPHSQCPWELNN +CVDQEEEEEMDHDEKDSSEEDVKCSEEERRDRSRARHGKYADNSYNEFGGLQLRGHTRGVTDVRFSAHYPLMYSVSKDAT +MRCWRAHNLHCAAIYRSHNYPIWCLDESPVGQYVVTGSKDLSARLCPDGKMLAAAGEETKVRIFDLAAGAQLAELKDHSA +SISSLSWSIHNQHLATACTDGTLRLWDIKKLSPMGSSPLDELLPLFSWSGSSSLDLDLPESSSFWLAVGVAAIEGSSSAA +TMAFHLETTLPKDSYNPGNDSFSKEVDYDFIEASPKKTGRTSKRKPPAAPREKPLTDEEDASPPKQNKQSQAETEKDEKA +EKDAPERALSPKHAQAGDAQKPEQAEECVVGPVARRTRSSLGKLEKQPPPVSVNVVVPAKKKPSKRGRKKAPSLAVIDVE +TASASVVSSLDSISFNLKNSRRQTMAEIAARSKVVDSIDLVSAVAPRVEGFVSLDSEDEAEAPALVDEANVFDNDNPTIE +VALSWAGEIQIYKLRQHQKFKHMFKEVAERNGVNENDVSVDMYYNFIGPDDTPHSIGLKSFHTLSGHATKSNNNNKKFTT +NDDNNPQALSRKPKKFQVKVQADKWKHPMVMPMKKKDTFKMLYIKCAEELNCDARLIKLFFDGELLDPEDTPKNQDMEGN +ELIDLQIKS +>A0AAD5MS85|unreviewed|Small ubiquitin-related modifier|taxID:148309 +MADNDSGAPASVDAAVEYIKLKVVSQDSNLVKFRLKTRMAMGKLKRSYADRIGVAVSSLRFIFDGRPIRDDDTPETLDLQ +DDDMIEVYQEQLEGRQ +>A0A8I5N9C8|unreviewed|Small ubiquitin-related modifier|taxID:9555 +MSDQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0A3P8XXE9|unreviewed|Small ubiquitin-related modifier|taxID:8010 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGLC +>A0AAD4QYX5|unreviewed|MIZ/SP-RING zinc finger domain-containing protein|taxID:166010 +MSNDCSRSLDLNDKIEEVIENSRTIEASETKAKIMEQFRGTNGVHVDVLRLSLLCPISGARLTNPVKGAHCTHVECFDLS +SYLGACVLQDHDWKCPICDMDLPQTHLVFDEYIKNILADTKPVIDYVELLENGEYRCNHPSLNGNIKLTVQNQQGRVINL +TVKLDTPMWKVKRVFVNRIGTPDALNTLRFCFDGRRVTDEDTPRSLEMEDNDTIDVYLEQNGGNLI +>A0A674E6L0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:8032 +MSDTETKPSSGDGSEKKDGEYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQLGMEDEDVIEVYQEQTGGLWHD +>L0PB42|unreviewed|Ubiquitin-like domain-containing protein|taxID:42068 +MSAPSEEDKKPTEHINLRVVGHDNNEVFFKIKRHTPLRKLMEAYCERQGKSMNTLRFLVDGERARPEQTPAELDMEDGDQ +IEVMIEQASTNV +>M7U1K1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1290391 +MADLDTGTSAPPVKKKFSLFKKKLTIAQAPELKPGMDHTDAFSRAKDLFPLHAREKEIKREKKIASLERKRSSQSREKSS +SSPRVEKRKFSNEDVQEKVDLDSETEDEELARKSSISTPDSRKSQTGSPQKKRRSPGGLMGRFAKDIHSRSRKSEEQEVI +AKGYISVSDSDSDDAAPVTQRISRSSSPIVTSAEPIPIIEDEDEDAFSEEEFPELLAKARENKRLADLAQERSNAEWANK +NHEPDRNAVDDDVFQDDKKAEPVLEIFISSRLENTKNLIIRRKLHQRLREVRQAWCGKQEIDGIHMDKELKDSILLTWRN +KRLFDSMTCASLGLDFNTNGDVDTTGEGFNSGRIHMEAWTNDLWDECCKAAEAEEISDDEEEEPVEVVPEPVNKMRLILK +AQSKDIKEFKTYVKPTTTIKKLVDGFRSTNQIPADKKIILSFDGDHLEPESTVEEADFDDMDTVDVLIR +>A0A0V0G8R0|unreviewed|Small ubiquitin-related modifier|taxID:72491 +QDPKPDSAPSESSDYIKLKVVGSDANEIHFRVKMTTQMGKLKKSYSDRVGVPVSSLRFLFDGRRINDDETPKQLEMRNDD +LIEVYQEQTGGCWCHYSSNQLF +>A0A3Q4B210|unreviewed|Small ubiquitin-related modifier|taxID:94237 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLAMRQIRFRFDGQPINETDTPSQLEMED +EDTIDVFQQQTGGSYL +>A0A0D2P996|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:29730 +MAVFIAASREAKRRIRELGKFFYSKFEICGIFGFFKTEKKLSVSLSDGNEVFFRIKRSTQMKKLMNAYCDKQSVDFNSIA +FLIDGRHLRGEQTPNEDGDEIDAMLHQTGGTSA +>W9VFW0|unreviewed|AN1-type domain-containing protein|taxID:1182544 +MNRSRSGSASSNTSSSKELPADNMAIQVQISGGKTIKLNVRPVHTVSNVLEFLSASTSLPADVQLMLDGKPLDPSTTVGE +LKLGELSTLKLSSPSRSPTAATDPPQQPQSEMTAIQPPTPSSSTPVPSSGASTPKKKSNKPRCSKDGCKTAAQPIVGDCG +FCQKRFCGKHRMLESHNCEGLADARKADKDRNTAKLQGERTVMLRGL +>A0A671KMZ6|unreviewed|Small ubiquitin-related modifier|taxID:1608454 +MSEDKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSYAFTWFPLLFLSLSLFCHL +>A0A7K8M0U4|unreviewed|Small ubiquitin-related modifier|taxID:449384 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A4W5MGI8|unreviewed|Small ubiquitin-related modifier|taxID:62062 +MSFLLKDMKPSSQDGGDPKDGEYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVHMSTLRFLFEGQRISDNHTPK +EVAMPSVVFYQNWTA +>A0A162AVE9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:79200 +MEDPNEELEPLFDYSRVQPLDLVCLDDDDDCVRIPPKKQKFTDGDKSSDADNLAGKAVIKIDDCDDEEDWLPSPVKISMD +TKKLEEDSIIKAIRLKKQELLSYAQSAEDILQNVDEPVKKDSDTSLHISSDCAAEPQPKPASERAKIVIGIQDKDEVKHF +RVYMDDKFEKLIKMYADKLKLDIQTIAFSFDGDKISPTATPADLGMEDEDILEVHVKAR +>A0A3L6QQV8|unreviewed|Ubiquitin-like domain-containing protein|taxID:4540 +MVRPGDDDEVDRKPVIKPGVHLTLKVQDTAGRTLERTVRRTEKLQALMDAYYASVPAVTYGTGRFLYDGGRLAGWQTPAE +LEMEDGDEIDFFTELLGGGGRAPASAAAADEQPVPA +>A0A8J8NJM2|unreviewed|Ubiquitin-like domain-containing protein|taxID:5974 +MTTAPATGAAADAQHINIKVKAQDGTEIFFKIKRTTQLKKLMDAYCTRQGLSANQCRFIFDGERLKDDDTPDKLEMENGD +EIDVMVEQTGGYGFNLSHFHSAKV +>A3LQF7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:322104 +MEDTEYKGTDVSFPGPESSIAPDIGKSVKSPKTKKKRSLLEDDFFSLSSTIDKKKGKKHRHKKHKSPSVDSTAPDTAISQ +ALDHSPEINDNSFNELTPASALTSVSTEPDVDVNVPIQSSYNSLVGDEDIAIVSIEKLSVAAPNTNKSAKSTTSLSPKRT +TTGTRNVWNSPASRTRSSIANENEVALEEEDEEDEEDDELHFFGSKPTHTISKPDGKYSFGDGNEKKRKYIIRVYSRLTL +PDGETDCWADFGTKGTKGFDKILASVLDHFRTKFRSNLPPEDLALYSASNAALVWIEGRMEMKSFFKPSTLRIPPPPLYD +ILENDVEKMEPTKLNCLLIPKRNALFFQSLYPEFQSEKEVESNRTVPEPEDSIAEVEPWVDTIEDEDDYEVTQIIEDETE +AYKKGEDSFFVIGLKGKDNKRINVQVSQDTLLRKLLLHYLKEKKIDEKTVDMKKAKLIFDDEPMDLDGRVGDTELEEDFE +VQVVI +>A0A671G7F0|unreviewed|NFATC2-interacting protein|taxID:59479 +PRKSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPTATPRTLKLGVADILDCVVLASSPEAVDTSDLLQLRVQGKEKHQ +MLEVSLSRDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLSGKELPADLGLESGDLIEVWG +>A0A3M6WFX3|unreviewed|Ubiquitin-like domain-containing protein|taxID:91943 +MGSEPVEEMPFTEPPPPQQPATPAQQDQLTLKFRDMNGFSIDFKLKPVTKLGKAMTAFSARMEKDPKELRFLSEGRRVLP +DQTPSDLELEDGDEIDVHMEQIGGHMI +>A0A9W8A1W1|unreviewed|Ubiquitin-like domain-containing protein|taxID:78921 +MSSSDEAIPRPRRVQPKPKRRPRPTATSTDSNGTSAAASAGPVASGPDDFFRRDTSNVLARIAQSLSSNQPSPVTKEGQQ +PRAEKSAVSAGPTQHRRSRSNNSNLSSPEQAAKQLAGRTSYNISDEDSAPESKGDRSPPALERVRTRSREVSLSPPPEEL +ALHYPYDEPLSTTSPLFSTTLRSPSTATTYADLPDPSLDPDLAAIATNFARHSSAGPDGLLSPRRDAPEPSHHIPLVVLD +SDEEQDHGHRDPSLPLASSLPPAATYTIHVTMVPCISFLACSDLDADPVYDTQYVSQAYHVTSTETLQALFETYCSTVLR +MPRHSLVMAYNDTRVFDNATPAGLGLHGAVEIYCYMRHTFEENRLRQEHRRQAAQQERAEEERLQALYAKKRPASSRTED +GATVDGPSGANGGQSNDSDEGAVTNSETDDEEEESSGFVRIKLRGKDGVDVKVKVPIATTTQTLVAQYCRRKKLDPTTQR +VQLEFEGEILDGSTTVEDLDLEDGDQISVVIRP +>A0A8C5DAM5|unreviewed|Small ubiquitin-related modifier|taxID:441366 +MSDTETKPSNQDEGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKEL +GMEDEDVIEVYQEQTGGFWND +>A0A7K6XHE9|unreviewed|Small ubiquitin-related modifier|taxID:254652 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A9Q0XHI5|unreviewed|NFATC2-interacting protein|taxID:171643 +MAEVDSCSSSDSELEGTPKKPLVKRRRLITDSAVLAVPVYSNKVQNSLQLFPKSLKLPTQVPELSSESQVLDASDEEGET +PATQVERETSRYQDQSPSPPPPPRPKRHCRRARILDQTLKNLASSLSAAKKSLQDDGAGADVILIEAPEPDKSQELVLKI +RCRTDLYRVSVQMTDPLQRVVEHMAHILKVHPNRILLLLRDRELAADATPVGIGLGVADIIDCVVETTSRDAAKLQLRLQ +GKDKNSQMDITVQKEEPFKVLMNRYRQAQGLGRRKLIFHFDGQQLVETWTPEDLGMESGDVIEVWS +>A0A834EGN7|unreviewed|Small ubiquitin-related modifier 1|taxID:89673 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0A2I2UYY2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9685 +MADEKPMEGVKSGNNDHVHLKVVGQDGSVVLFKIKRHSAFSKLMKACCEQRACQ +>A0A4W3GEU0|unreviewed|Small ubiquitin-related modifier|taxID:7868 +SVQETGRKENEHINLKVAGQDGSVVQFKIKKHTPLNKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTID +VFQQQTGGLY +>A0A2H5PS52|unreviewed|Small ubiquitin-related modifier|taxID:55188 +MSGVTNTPQEEDKKPNDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVELNSIAFLFDGRRLRGEQTPDEL +EMEDGDEIDAMLHQTGGMLMF +>A0A484K5U4|unreviewed|Small ubiquitin-related modifier|taxID:132261 +MSGITNATVPNQDAAGLNQNQQEEKKPSTADQNHINLKVKGQDGNEVFFRIKRNTQLKKLMNAYCDRQSMELSSVAFLFD +GRRLRPEQTPDELEMEDGDEIDAMLHQTGGSLCGVIIYTN +>F8Q349|unreviewed|Ubiquitin-like domain-containing protein|taxID:936435 +MSEEDQQVPPQTQDEVKPADDNAPINVKVVTSTGDEVFFKIKRNTKLSKLQGAYANKVGKDVASIRFLYDGSRINDDDTP +SSLDMEDNDTIDVMVEQVGGSFVLGYSHQHCS +>A0A8J4NMK6|unreviewed|Small ubiquitin-related modifier|taxID:37083 +PQQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGVY +>A0A8G1R9D9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1448313 +MADSGEAPAAVEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKQPSTVRFLFDGTRVRPEDTPDTLEMADGDTLE +VHQEQIGG +>A0A4V1XYH0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2211644 +MQRPQEFIGVSYAGRGIYIKKPATWDDLLRTVSQRFQLSYATAASLRALYSSDMSGTSPHWEMDASAWAGVKPDSSIYLE +SNESLKEEEEGTGPSDEDSGRPAVRNDIHNPTKVVLNLEGPDINCKVRVRRTITVERFMCLIKKELDLDDLDIICLFEGN +RLLPNDIFESLDVRDGDTIEVYISQTAGKPAIYLLSPTFLEAVKVSVVLRPEWDFTVLYPLAPITKSVDDSTSTVSWTVS +VQPDGTLTKHSTGRQSSYLFWEARSLLSSTPRLLSAGEHDSAFDPCNPTVFFERWHANVTLPFDRFEPYLDSVLQSFTLT +PAMRTEFIVYWLPSFQRIRDRGQDIRFTFVPQEAFNKAAELTVEGAVPKAVARVFMLFGGVENQELRSPDAVHQTSTEHA +SEIDWPGVIGLDVQGMEDESAFRVLEWGGMEWPPDYLLISAPRLARLVTLDHMATRRTMPCTAYNARGWKASCNDCVTGD +PIRKFTDDSKQLTSQLKAQAALRNQLSLKPRQKASCEGSVAKSTYTTRHMV +>G1PXR8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:59463 +MXXXXQQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQDIQLEMEDEDTIDVFQQQTGGVY +>A0A8T0VM59|unreviewed|Ubiquitin-like domain-containing protein|taxID:38727 +MVSPCRKQEESASPARVIVRRIVAAAAAIKPVMLVTLKVEDTHRRVVKRTMRRTDKLQGLMDYYYDVVLCTADGGARGTG +RFIFDGKRMKGEHTPEDLNMVSGDKIDFFQDLLSG +>A0A7R8UA21|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:343691 +MDISLDVFAGVNDFCENYTPEAIKLSKSQIDEDEEASDSEAEAFFLNGKGNKPKKQPKEPKVGRRKRGPKAKDTLDRESS +SEETEEEPSPPKQGKNQNNKDDYIPDVEEIVIEEVSETGRPKRTVARPIRLVEEYMQRQTAAILQQQAAVVPRRGRGGRR +RNTPQTACNAPIVGVIDLAGPKTPPLPPWSRTFSEKTVNLESDDDCNFSSDILNSSFDLENETLSVKVKWGDKIEMVPLR +KHQKFVDIMMEFAKKKSVDPKDILLNLNERIIEPDDTPDSINYNIAQFISGRIVPNANHIVPAKKKDPNMIKVKVQSNAF +KKPLSVHLRKDQPFKDLYFKCWEELKIPADRIKLSFDGDQLMLGDTPNDLEFEGGEVIDCRITKK +>A0A8T0CQV7|unreviewed|Ubiquitin-like domain-containing protein|taxID:360336 +MDIAATETKLVFLASVGRKNSRPDPILLRVKNQEEDDVCYLLDRSMPLKALMAEYCVRRGLSYGAMRFTYDGTRITEAKS +AEDLGMDDEDVIDAWADQLGG +>A0A7K7ZYE5|unreviewed|Small ubiquitin-related modifier|taxID:254552 +PQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTID +VFQQQTGGVY +>A0A6P5S1J3|unreviewed|Ubiquitin-like domain-containing protein|taxID:42229 +MGIGRRVPVGPQRNILGVPKQRPSHITLSVHDHLGGNDLVFRMKRSTQLWRLMIAYCDRKSVAFNRMRFAYDGVPLLSSR +TPDEYDLESGDVIDVIHAFPVLRGGGAP +>A0A3P8VRZ8|unreviewed|Small ubiquitin-related modifier|taxID:244447 +MLVPKCFCCLLQEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQL +EMEDEDTIDVFQQQTGGSCS +>A0A2H3DB06|unreviewed|Ubiquitin-like domain-containing protein|taxID:47427 +MSTIASSSQLSPPPKVKTDAVEVVSHSDSITLKVLSTTGHEKTFKLKSNTSLRKVFHAYAQTTGKDIDTFKFIYEGQRLN +PQYTPEMYSMENEDTIDVMLEQIGGKTEI +>A0A8C6U2D6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:47308 +MADEKPKEAVKTESSEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQLEMEDEDTIDVFQQQTGGYF +>A0A8C3NFD8|unreviewed|Small ubiquitin-related modifier|taxID:87175 +MLEEKPPEGVKTENECIDLKVAEQDGSVVRFRIKRHTPLGKLMKAYCCRQGLSMRHIMFLFDGQPIKEADTPAQLEMEHD +DTIEVYQQQTGGGC +>A0A1E4T0Q5|unreviewed|Ubiquitin-like domain-containing protein|taxID:983967 +MSDAEQKDTHINLKVTDGTSEVFFKIKRSTPLKRLMDAFCKRQGREPSGTRFLYDGQRVSAEATPDELDMEENDVIEAHR +EQVGGC +>H0WCS2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:10141 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>A0A0L8FRL0|unreviewed|Ubiquitin-like domain-containing protein|taxID:37653 +MLHSSQMPTQKHTATTSGTRTRKGKKSNDGCALDDSVVIVDDDADDGNDGCCITEEGGGGDDDGGGDDDGGGGSRTSNSL +DSHCSIPENRRIVVLVKVELEVKRFEMNYNDTFSQLFAHLARELQVTEDHLILLLNNTTIHLNETPASVRLRAYDILVCL +VSVDTDCGQNMAERTGPNIFQLVIQSNGLKRCNVNMSVGKFETFQSVLDIYRKQQNLNTELLKLYFDGELLKPTLTPAAY +GIEDGDCLDLVVQT +>A0A1U7QQ51|unreviewed|Small ubiquitin-related modifier|taxID:10036 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGTAPRGTVPTPNHCPDICY +>A0A2K5DKM2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:37293 +MSDQEVKPSTEDLGDKIKNEDIKLKVFGQDSSEIHFKVKMTTPLKKLKEWYCDRQGPTSFYSANSFLLSLSISLSLSLSL +SLSLSLPPSVSLFL +>A0A9P5VTK9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1896193 +MGEEAEKKPEPGSVEHINLKVVAQDQSEVFFKIKRSTQLKKLMEAYCERQGKSSNSLRFLYDGERIQPTNTPNDLEMEDG +DSIDVMVEQVGGTL +>A0A2K6D4J1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9545 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>S9X298|unreviewed|Uncharacterized protein|taxID:419612 +MPSPLLFLALFLVPAGIRAREPHLVEVKEGGNAVLSCLGGPTDGPTEQLAWFQGPQSKPFLELSLGLPGLGVHVGPLGTL +KEPQGTLLFIFNVSDQMGGFYLCQPGPPSEQAWQPGWTVSVKGSGEMFRWNASDLNDPSCDPENSPSKGSRPSSGHPTRP +QLYVWVKDHPEILYTDPACAPPNGSLNQSNNQDLTVAPGSTLSLTCGASRSSLARGSVSWIYVHPNKRRIPLLSLKVRED +AQPRERWVLGTPGGKAVLVLPEATAQDAGTYHCNHGNMTTQMRLKVTTQSALILRRKRKRMTDPTRRFYKVTPPTGNGAQ +SQYGNMLSLSAPHSGTGRALRWAAGLGAAGQSYGNPHSYVQEARAAGSWSPPGGGPEEEEGEAYEEPDSEEGSEFYENDS +NRGQDHLSQDGSGYENPEDEDSFSNAAESYENEDEELPQPVARTTDFLSPHGSAWDPSREATSLGSQSYEDMRGILYAAP +QLRFVRAQPGPNHEEEPDIADSSSPRAEDSPCPESPWKKKLRSKDGEEKKKVLPKMDVTRRVEDTSPLPPPPPRTKSRKH +TRALQKLREVNKRLQDLRSSLSPKQPQGQEHLSQEDEVVLVEGPTLPENPRVLRLKIRCRADLVRLSIKMSEPLQSVVDH +MAARLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVLASSPEAAETSQLLQLRVQGKEKHQMLEVSLPRDSPLK +NLMSRYEEAMGLSGHKLSFFFDGTKLSGKELPADLGMESGDLIEPPPLAGGIVGGTRALAGTMSGSDTTPFLSQADDTND +GPVPGTPAMPGSMGIPKSEDPEVPVREGLQRITGLSSGRSALIVAVLCYINLLNYMDRFTVAGVLPDIEQFFDIGDSSSG +LIQTVFISSYMVLAPVFGYLGDRYNRKYLMCGGIAFWSLVTLGSSFIPREQFWLLLLTRGLVGVGEASYSTIAPTLIADL +FVADQRSRMLSVFYFAIPVGSLIFGLITCLTGVLGVGLGVEISRRLRRSNPRADPLVCAAGLLGSAPFLFLALACARGSI +VATYIFIFIGETLLSMNWAIVADILLYVVIPTRRSTAEAFQIVLSHLLGDAGSPYLIGVISDRLRRDWPPSFLSEFRALQ +FSLMLCAFVGALGGAAFLGTAIFIESDRCRAQLHVQALALIPPLAGLLHEAGPADDRIVVPQRGRSTRVPVSSVLI +>A0AAD2G5V8|unreviewed|Ubiquitin-like domain-containing protein|taxID:2856 +MSDSSSSDDEPLMESPCESDGDSDDDKDVFRYDRRRFIKAAPTAPTQDKLATPARAQRRRLKPSTDDQMSILEKRQEKKQ +KTLRARIDQTSTLNDDSDESIDDSNYPNVNADADTSIEILDVPDEISVLAATRESKKVIDLADSSDDDENVATIRSNIPT +SDPLLQRSRLARLQLRQAQLYHAEDVDVDTTELEAVLPFTVSKASRTQELDKQAVENIGENMQIACIIKREINGKGQNII +KRQFLIKQNEPVQKLVSKILEADSLPASSRVKVVFHGVILEKHRTPASYNMVDEDQVDVEIAANIVPRLNSSRTKSDYGP +SLNLKLRRRVGKNVQEIEMRIGSRQPLQQIIDLYREQQNLENQNVSLHFDGEKLDLSKTPLAYDMESGELVDVNCKGRGD +GN +>A0A7L4IND8|unreviewed|Small ubiquitin-related modifier|taxID:932028 +MFLQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A8X8CAT0|unreviewed|Ubiquitin-like domain-containing protein|taxID:118781 +MSGVTGQPQEEDKKPNDQSAHINLKVKGQCLGNDSDLHNRYEDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFD +GRRLRGEQTPDELDMEDGDEIDAMLHQTGGAMKTSN +>A0A139IDQ1|unreviewed|Ubiquitin-like domain-containing protein|taxID:113226 +MSFFKAPAWAKAPAREKSDDEKDLFSHSDKFLEVQRDTIEQKKKRAERLKQKEQEREQRQKEKTEKRERKNAIKRESTGE +DGKNGLKKRRINSEESAKLLALASANPIMIHSDDDEATAAPVSLPVRRSPRHQRTKDMFPSPRKPKSTLSSAIEAGDSNG +EIQLTTVKAKPARQPEAEEDEDSDPEIAAIKRAARERHRQKLQKERCSTPNGMTLEAGAEAGRSRTPPPADPTISLLVTS +DIPGTEPLLVKRKLSQNLKQVKDAWCQKHGYSKDMAEKIFFAWNGRRLYGVTTCQRLGIEVDSRGNVVRADDRAADGAAR +VHIEATTEELFAQSKAERARGARSDSGLYEDEGEQEDEEREAEPAAKQQIRLTIRAKDKDDVRVSVSGATLVSKILNYAK +KQLKIPDEQLAYLHFDGERLNPDEPVSSTELEDKDGVDLLPAYTACLGPLHGMAANDDSHGAMLHVTSLVHRAVKPAYTL +PPSRRRPLGAATMTISEDDAHPFVWFGMAPKAQNFGNSCSNGATLLLPGRGLGIVTLRPQSQIRNHAAAAAAAAATIDSS +RQNNRSSTFLGDLIAPLRYRSKHPPSPEIRAGTGWLPLTLKLTPSPTPNVAPDNKRIISLPLPANNPILDLETARRNYNF +ESFFGQAIANNGRRCCGNYMPLAFLILREHPENWTIVARPPNRQARATIQATATAAALHFTLLASLEGGTVPPWIRKYHC +YFPWASAYNNLIDAISMASRVPQRGAARITPPCTSATAVKAASADNKLQRRPASTAAFSVRTDSDRVIHVYSADRTSSGG +SASARSPASSGGSRSFSSDSWSEIDDDDIEPSDSASRSRHPSRRHTVEARPAPTRRQSSRRVVEREEIEEPRRRHSSRRH +HSRHESRHDSRHGRSSSRRVPSDESSSSVASPDDYPPYGHHGMPHAPYPHSGYRHVPAGSRGGYPPSVATAPSGYPDPYG +REQQLVSMRHDPFAYPSHSNPFSPHSQQQNPFSPIRDDQSNYFAQEPMAPPPPRRHPSEVRRPQSFAAPSHYETETTMMA +PYAHPYPPGPWGMPNYPPYPPVPGWPHSAGSSPPPPKEEKNAEIEELRRLMEKRNEDEHKEKKDKNSEIEALKELIKKHE +EERVAREKAWIAEREAEAAAKAAEKAKAEEEKKRKAEIDEAKKKAKEDAEKKAEEAAKKAKEEHEKKLAESEKAKEEAAK +KAKELEDEIAKNKPTPDSLKAPIRFKDAVGRKFSFPWHICKTWKGMETLIKQAFLHVDMIGEHVHQGHYDLTGPDGEIIL +PQVWDTMVQPDWEITMHLWPMEEEKKPPKDDLPDPFANLGMGGGFPGDFGILPEHGLPKKKGAKGKDGKAKKPKGGSPDI +IDVFPGELPVGKGSMPPPPPPGFGDPFAAMSFPGMPAESKKARPKSKSVKKEISPLAAWFAGGAISNSKAKRSK +>A0A7J8YB82|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:34290 +MDMKKMVQITLYNQEKEEKRILLKLNRVGCGDEADQYCYSISQSIPLRDLMLDFIKRVGVTFNSVRFYYEDKPINPAFNA +KWLHMKDGDTIAVSRRRNFRPTAATQSTLITLPLAVVGEKPVVLKVDDFRADGALYYYLIGRNTPMKNLLLDYADRVNEL +YEQVSLTCSRFCRIDMGKAADDLGLEDGDVIYAFLFAMRAC +>A0A7J7QNZ6|unreviewed|Small ubiquitin-related modifier|taxID:2650976 +MAELRAMADQEASGENKPQPKQEGQVINLIVKDQQGSEVHFKVKSHTKLEKVMKAYCEKKAIELAAVRFVFDGQRVNPQS +TPQNLGMEDADIIDCFMEQIGGNK +>A0A8X7YS00|unreviewed|Ubiquitin-like domain-containing protein|taxID:118781 +MSGVTGQPQEEDKKPNDQSAHINLKVKGQCLENDSDLHYLYEDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFD +GRRLRGEQTPDELDMEDGDEIDAMLHQTGGAMITSN +>A0A851PUC3|unreviewed|Small ubiquitin-related modifier|taxID:56067 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A8D0I4J7|unreviewed|Ubiquitin-like domain-containing protein|taxID:9823 +MIPKEGVKTENTNHINVKVRGGGQDGSAVRLKIKRHTRLSKRKKAYCEPQGLSMRQIRFRFDGQSINETDTTVQLDREDE +DTIAVFQQQTGGVYERGTCFLTPESCCSRPRRHSQ +>A0A4Q4RJG3|unreviewed|Ubiquitin-like domain-containing protein|taxID:156630 +MSDNGSPNVQQKPEDGGQSEHLNIKVTDNNNEVFFKIKRTTALGKLMNAFCDRQGKNISSVRFLFDGQRVTAADNPDTLD +MQDGDTLEVHQEQIGGC +>A0A8H7WJG1|unreviewed|Ubiquitin-like domain-containing protein|taxID:108018 +MDDFGDLSAEEAPAPPPPPKIKKSLFSKKITTKIPDSEEPVDFYSRAKDVYHIQQAEEERRRQKKLVKLERKRSSTSAEV +REKSPSGDKRRRVSEQRDAYSPEVDPVNDVVETNESRRNSAHSALSSQGKERYRVRGSPKTLSARYTKELSARKSDSPQP +QRDIAKGYISLSESDEAGASDGGSGSVNGASTLAARKRNQAISLDDDDDDFAIAPRVIRPPPPPVEDDANVSEEEFPELV +AAAKERQRQQAALKAKAEAAAAGKPQGDLDGDDIFDTDTNSTNMEPIIEILVTSKIQGTKPVGVKRKLYGKLREVRWAWC +DKQVIDGQKMSEEVKESIFLTWKGNKLYDFSNCSGCVEGEKLAMGSVGDGKVHLEAWTEETFEAWKKGHEAKQRGEREHS +EDEPVPEPDPVQRTRLIMKSRDFSDYKLMVKPHTTIQKIMDAFRREKNVPDEKDVTLHFDGDKLEPDDKVKDTELGDMDS +VEVHIQ +>A0A077Y9N2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:5861 +MADDNAAANNNGSTGTTQGEHIQVKVRSPDGAEVFFKIKRKTKLEKLMEVYCNRLGQSIEAGTCF +>A0AAD2E3B7|unreviewed|Ubiquitin-like domain-containing protein|taxID:56036 +MLSDYEKHLLCMTKAKALYFMSSSYWILWGYTLPAESQRGILSKFLCVVLEGQTAALERVIAKSKADRRMSSAGQDEDKK +PGDSSSHINVKVKGQDGNEVFFRIKKGSQLKKLMTTYCDRQSVDLNAIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQ +TGGSAAA +>A9USN3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:81824 +FKIKRHTPLERLFQAFCDVRRLDRQRCRFWWESFELQSQLTPELAGIADEDIIRC +>A0A1V9YAZ7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1202772 +MSDQEDKVAADGEDKKQTITIRVKDQSGEETFFKVKPHTKMEKIFSAYAQRKGVPVSALRFLLDGTRIAPDQTPKMLELE +DQDQIDCALEQVGGC +>A0AAD3N1E5|unreviewed|ADP-ribosylation factor-binding protein GGA3-like protein|taxID:270547 +MADDGESLESWLNKATNPSNRQEDWEYIMGFCDQINKELEGPQISVRLLAHKIQSPQEWEAIQALTVLEACMKNCGRRFH +NEVGKFRFLNELIKLVSPKYLGDKVSEKVKSKVIEMLYSWTVSLPEEAKICEAYQMLKSQGIVLADPEIPLDATLIPSPS +PRPKNPVFDDEKKSQRLAELLKSKKPDDLQEANRLIKNMVKEDEVRTQKATKQKSTLEAVNNNVKLLNEMLAHFNPEDST +DGDKELIRELYGDCDKLRQTVVQLATETEDNDSSLGDILQASDDLSHVINSYKKIVEGQTINGETEEAQQTQTSVRQGTG +RTNQSEILIDLVGLDVRSPSPPEQQPPAPSLTFPADLLCGSAAAEPQSQSPSAPSAALSLLDEELLSLGLNEPTPVDSSQ +DLHLFDTTSPTGPTFSTSSLFPDALPATVAPLNPTKSSTAASALTFPGPVLAPPVFTESVPTTSVVFPQPLSSVLTTLTP +SALPQSFTVDSPASSATHVTPQQVSSPPGAPHSSSTSLSNNLQDLSLLDLGSPKNTHGVTDFGSLLVKSEDLCTPATLSS +SLGVSSTTSTSLVTGGIQGGSALPPTKSQADDSPLLRSLSPILPLSQASPGMGQEVSLANVFVPLDAIKPSKVSPVTAYD +KNGVRVLLHFATDCPPGRPDVLVIVASMLNTAPQPVRNVVLQAAVPKTMKVRLQPPSGTELAPFNPILPPAAITQVMLLA +NPLKEKVRMRYKLTFTLGEKPLTEVGEVNEFPPADRWAGSTAAYAKWRASQRSRTRIGAGRHSSTAAMADEKPKEGVKTE +NNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTGG +SSL +>A0A8D8RQN4|unreviewed|Ubiquitin-like domain-containing protein|taxID:428564 +MSLNSSMDDDDDDFDFYNNPIAQFNKIKEQKEKEAAMKRKRLEKKLDELDASMTEDKSKDETEVSSSNKVQLEGLVIEIT +DSQSPKINDVEIPESPPKNQGLRRSTRNRGRGRGQKNAITDYFTVSETKKNSRKNSLDRELQQLEEVASQLKATTKSKNV +PLLHDSPVLIDSDDECEADEIVNVKVVWRQSEPYSFPIVKKKDLGSIYEFFAKRENVSIQKILLSKKDQVLSPHCTPLSI +EYKVTDILEGGILEETVNNQQAAVNKQQDKNCIEVKVQQKNVKKPLLIQLHKSNDMHILAKKVAAELGIDIEKLKFNFDG +DLLDLDETVESLDLDGGECFDLVIIS +>G3TMN2|unreviewed|NFATC2-interacting protein|taxID:9785 +MAEPVRRRGRTTRGGGVGRGARGARGARGGRGRRPHAQRSPARRTLDSVFVDLISDSDEDILEVATALGATDPAEAPLPE +PPAPVASRDDSDSDSEGADARPEGAPRTAVRRRRRLLLDPGEAPVVPVYSEKVKSSLHLIPDHLPLLELCPAGAEEGKEI +VSNHPPPNSNKRGECRPWTRTVHLSSQPEDPPYPGFTAQDMSPSPPSPPRTKSRKHTRALQKLREVNKRLQDLRSSLSPK +QHQGQDCQSQEDDVVLVEGPIFPQSPRLFPLKIRCRADLVRLPVRMSEPLQSVVDHMANHLGVSPSRILLLFGETELSPT +ATPRTLKLGVADIIDCVVLASSPEAAETSQQLQLRVQGKEKHQVLEVSLSPDSPLKTLMARYEEAMGLSGCKLAFFFDGT +KLSGVELPADLGMESGDLIEVWG +>A0A4W5KNK8|unreviewed|Small ubiquitin-related modifier|taxID:62062 +MVISRLPLAWDQTDHLLCINCISQATFASDRPRQVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTI +RQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTGGLY +>L1JJ13|unreviewed|Ubiquitin-like domain-containing protein|taxID:905079 +MEVKIRPAGSRAVEMAMHVESRTTAKDVKENLLGSMNLDSISKLFLVYNGKIVDDESTFEEIGVKEGDTIFSVLQDQAPT +WKLEKQEEPGPSQEKIPASLPAGQGEDDPILIRIKELENSIFHLQRSNVELQAAGPDPVYEEAIQENIVAIAKKTAEKEE +LRRLREEEAMSKGQPCQVSDSSEQRNGGDGGLYL +>A0A9Q0GDF0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:218843 +MPGDGDENPPKNNVNKNQRIPISVQGQDGVLVDYKLAYNSQLSKLMDAYCKRKNLDAKVVEFLYNGQRLRRTSTPAELEM +HMEGDQIEAVQRVHGGGGCKGIKRLAV +>A0A6G1IAB0|unreviewed|Ubiquitin-like domain-containing protein|taxID:703511 +MSPLGMLKPSEDDVDDDDDDEDDPELRELARRARERARARQQEAEGQSAEALSNEPNPIISIFIHSETIPDTRELFVKRR +YRQRLREVRLGWCKANNFGPVLTSQVFFTWRGRRLFDSADFRSVGVKLDEFGGPMMEGEGFNDDRIVFLATTQELETKAR +EAEERRRREEEAAAGGDEDEPEAAPEERIHVVLKAKGYEEFKLVVKPISTFAQIANAFRKERDIPANKEIILMFDGDCLE +PEDTMAQSEIEDLDNIEVYLKD +>A0A1U8KB99|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3635 +MDMKKMVQITLYNQEKEEKRILLKLNRVGCGDEADQYCYSISQSIPLRDLMLDFIKRVGVTFNSVRFYYEDKPINPAFNA +IWLNMKDGDTIAVSRRRNFRPTAATQSTLITLPLAVVGEKPVVLKVKHFRADGALYYYLIGRNTPMKNLLHDYADRINEL +YEQVNLSCFRFCSIDMGKTADDLGLEDGDVIYAFLFAMRAC +>A0A5G2QLK1|unreviewed|Small ubiquitin-related modifier|taxID:9823 +DSDEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELG +MEEEDVIEVYQEQTGGHSTV +>A0A7S1IV32|unreviewed|Ubiquitin-like domain-containing protein|taxID:73025 +MSELRVHGPRATHALAPPAEWPGLRLINTLARLDGQVHALAETLSRRRTAFREALSEVAALNEAQLEVYRLDVGGRAFHT +RVEVLQRKEGPLSMMASEVFATDVDEDGYAFLDRDPAWFPLVLHSLRAGVALLPEDAEGRQAVFREARYYNLDLDVISLV +VISPEGDELRCGFKVSIPLSKLMDEYCSQKGLKRTRVRFRFDGRLLRYDNTLTAADYGMEDDDRIHAFCACPNEVISLVV +ISPGGDELWFKIKLKTPLRKLMRAFCNKKGLESTAVQFYFNGRFLHYDQNLTAEDYEMGYDDVIRAIHV +>A0A2K5WHX7|unreviewed|Small ubiquitin-related modifier 1|taxID:9541 +MSDQEAKPSTEDLGDKKETKYIKLKVIRQDSSEIHFKEKMTTHLKKLKELYCQRQSVPMNLLGFLFESQRSADNHISKEL +GMEEEDMIEAYQEPTFNSLDILFIFLLPSIFKFFFCNVVFKMKLKTGTPIFLKQLLI +>A0A818LAI6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2762511 +MEDDEDDFFAYQTAKSLNNKRTQLKQFLQAPVTSQQLSSSSNSDSDSENDLISIKKTKSKSVDIPTQSIIIQTETIKTKD +VVKNEIDAIVTSCFTSTNKEVKRKIKLGKRTAADDQEYENEDEYLTYCLDQSRNRSRNRNISRAQMNLLNKSQLEEDDEK +VTRETAAYNRLDAVLRVTKPLCEKQIESIDYDEDDDDEEENEPIKTNISNGIDVIDPVETLSFDTITLKIDHSDGRQLTL +SLPLSTTLKNLYDQVAKRLSLPSIYLVYNNQTLKLDDNNQLMTLKQLNFSSDNIQLLESYPLVRKLKIFIQTSSSSSGRR +SSFIPKREYKMLDTDRFEIIFETYKRDVKSTNIRFEFDGYTLHPHATPSDYDMTDGEILDAFILSTSSNTNKQNNQTKTK +KTKEIIFDDDSDN +>A0A026WLH5|unreviewed|Ubiquitin-like domain-containing protein|taxID:2015173 +MTTQMGKLKKSYSDRVGVPMTSLRFLFDGKRINDDETPKQLEMENDDVIEVYQEQTGGR +>B3N676|unreviewed|Small ubiquitin-related modifier|taxID:7220 +MSDEKKGGETEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIE +VYQQQTGGAL +>A7WLH8|reviewed|Small ubiquitin-related modifier 1|taxID:9823 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A4V4M6Y9|unreviewed|Ubiquitin-like domain-containing protein|taxID:245174 +MAENETNANDGKVNLKVAYSQGGSEDEIQFSVKPTTKLGKIFAAFCQRTGQDQSTVRFTFNGDRLDPDDTVKQYEMEDDD +QLQAHVSQIGGL +>A0A8C5KJG6|unreviewed|Small ubiquitin-related modifier|taxID:51337 +MADEKPKEGVKTENNDHINVKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMREIRVRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGSVY +>I7MFS9|unreviewed|Ubiquitin-like domain-containing protein|taxID:312017 +MTDQNANANSEYLNLKVKSQEGEEIFFKIKKTTQFKKLMDAYCQRAQVNAHNVRFLFDGDRILESHTPADLKMESGDEID +VVVEQVGGSF +>A0A2U1J6J9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:133377 +MESEDSETDISTLNFAKKIVQPREIHLSKTTIITPKPKLKILPKSYKAPDKFKKPVISISSTKSNPKSKYIRDLDSDSSD +DAFFSREISSEQKSKLIKQVSIDTKKYQSIELKNSSVFVDTIKSDSDSSISENVRSSPKSEKRIQSFTSESDSDFSSSSD +HHKQQSKKIRNSDNYIGSGNQFSNGEILKNDSLNESSSDCGYTDDDSISIETDRAKATSRIPLFFGGMNNFYTPHPNPFI +ENDTEAVYEGLDPALMEVVKSHKKHQKYKLSGSTIKNENSLKSKLDTENQLPSIINLDEDENESINLILNLKLDTNFLND +EIKNTSAFHWNKESLVFNNDFDFEKMESLKITMASNDTFLKTLETLRLQLMIPFDTSRLVLVYDNVKVYPTVTPRAISTS +ETIEMDVYPTNVYNRFVKKQKNNFEQVISDPPTLADMTLESDDLDLNVDSEALDAIKANKTTEETFKIKIRSKLGKDIYM +DIAKSVKISFVIEAYKKACELGNEVKVKLSFDDESLNPNDKIGDTEIEDDDMIMASF +>A0A8C6MX21|unreviewed|Ubiquitin-like domain-containing protein|taxID:10103 +MKAYCEHQGLSMRQNRFRFDGQPINETDTPAQLDIEDEDTIDVFQQQTGGVY +>A0A1S3FFI2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:10020 +MADEKPKEGVKTANNDLIHLKVAGQDGSVVQFKIKRHTPLSKLMKAYCEPQDTPAQVEMEDGDTIDVFQQQTGGVY +>A0A9P5CWZ4|unreviewed|Ubiquitin-like domain-containing protein|taxID:101480 +MASFFKKPTWAQASTPTKPQDFFRRSNQVYSDFVATTQDEDETDDEAVAAKETPCVPSEPKRRRISNEDDGETTPALQSR +IKSPPQETASGGDTVKRDTPPRLEEAETSKTSPRSPRSARSSPRKTGSQRNSPRKSQLVGASPPGTIIRLNSESPPPPAS +RVPPKSVIQIDSDLDNDGDNDEESDEECAALIRRARERARNNLLREENKSASPNDKDNDTRKTTGTPSTSPKAASSSSPK +KKDTVVNILITSNIQNAKSLLVRRLLSQNLGEVRKAWCNHQKYDEATSDSIILTWKGRRLFDVTTCKSLGINDTDTNDNS +MFDSSPFDMEEGNAGVHMEAMTEEMLEERRRAATTIQQDNNEEKSEEEQPKAQEPADTDLLRITLKNPDLDDLRIKVRPS +TQIGNILKKFRQVKEIPEHKSVSLYFDGEKLDPDTLIEDNAIDDMDCIDVIMK +>A0A5K1U8I7|unreviewed|Ubiquitin-like domain-containing protein|taxID:5759 +MTFIDLDASEENHYHLSYIPSTKSQLEQEFGNKKDMISVYILRDKEKTQIQISKKATILELKEKYLKSAAPALTLKFMGM +LLNNDKTLPDYTIGDQDCLDATLDRSSIDSSQYIKLKLRFENEIHLFKISPIDKLEKLFEKYANKINKPMDRLKFIFDGY +ILSPNDSCQSLELENNFIIDVQEIH +>A0A9P9QNX2|unreviewed|Ubiquitin-like domain-containing protein|taxID:2138324 +MDQLWHAAILDTQLYAGLQDALGLVIHHRPEGASDKEAEQRARRLSVMEGIYKTFFSTKPLESRPYTPPASPPQPPAVQS +DMHDANEIRICVRTPAAHAIYFKVQPHAKFSSIITAVTDRMKISRKTIRLFHEGHRIKEYVDTIASRGVRDGDVLEVFLE +QGGC +>A0A9J5XGB5|unreviewed|Ubiquitin-like domain-containing protein|taxID:4109 +MSASGGAGDEDKKPNDQMVHINLKVKGQSGYWVSDSLHFLFTLVYLESDGNEVFFRIKRSTQMRKLMNAYCDRQSVDMNS +IAFLFDGRRLRAEQTPDELEMEEGDEIDAMLHQTGGSDTGFCTCFSNF +>A0A395IS18|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:38457 +MEAWTNDLWDECCRAADAEVINSDDDEPVEEVAPEPSTKIRLVLKAQSKDIKEFKTYVKATTTIQKLVDGFRTTNKIPAN +ERIILTFDGDQLDPDGR +>A0A7C8MHC7|unreviewed|Ubiquitin-like domain-containing protein|taxID:100035 +MSDSGSPNMQKPEDAQPEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKSPASVRFLFDGQRVGPTDNPDSLDMQ +DGDTLEVHQEQIGGSW +>J3MMB3|unreviewed|Ubiquitin-like domain-containing protein|taxID:4533 +MRRSGGTVAVKVEKADDGKTPAAGEFVTLKVQDTDGRVVYRTMRRTDQLQGLMDFYYDRVQEWVATGTGRFLYDGRRLRG +WQTPAELLMEDGDEVDFFVELIGGAGGHAV +>A0A2K6JWV8|unreviewed|Small ubiquitin-related modifier|taxID:61621 +MVDEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPHSKLMKAYCERQGLSMRQIRFRFHGQPINETDTPAQLEMED +EDTIDVFQQQMGGVY +>A0A8H2WDP9|unreviewed|Ubiquitin-like domain-containing protein|taxID:456999 +MADITPSQDGKMMITITHSKGAAPDVRVAVKKISQLRKVFVAAADRFRTTPDELVFKYNGNILEGDHTPKMHEIPEGGII +TAYPAGEEEPSTQNLQNTQVSNDGGFGANDRDDQGDPSASAKNDKITLVIRSQEGPSFQIKVSRTKPLRSAFDKAHEQFK +KAPKTFRFFYNGTRLQEDDTPKMHEMENNDEIDANIQQVGGAPLT +>P55854|reviewed|Small ubiquitin-related modifier 3|taxID:9606 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGVPESSLAGHSF +>A0A8D1ACV7|unreviewed|Small ubiquitin-related modifier|taxID:9823 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDE +DTIDVFQQQTGGGPRLSGCRL +>A0A015LEF6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1432141 +MTSNDQLLSQYIKSEAVDSNKSTDDSFINLKVRDYSNNVTVYKVKRTKPLNKLMQIHCDRNGLNIQVFNFYFDGIRIKDN +YTPDYLEMENDDDIHVVASQIGC +>A0A914Q0W1|unreviewed|Ubiquitin-like domain-containing protein|taxID:227884 +MRIEIHSFNGVHFDLDVEESETLKNVKQKIRSKVNYPINQQSLIFNYNKIDDDDKALSAYGIEDGASLQLRIAGEWKITV +ELMNDLVISMEINPNYTRRIRELKYIIQHKTQTRAEIQRLFLNGNELLDAAYICEAGIQDGTILVCRPKMEILVNISGRK +ITVGTKEDDYIKEVKRQIRVMEELLSHKLRLMLNGTELDNMKRLCDYGIIDGSEIEMYKEPYKNADFVNIAVVDQDGTEY +HFKVKMTTSIHKLKLVLQDKLKIPFAQYRLLFGGHRINDFDTIHKLGIHDGDEIGMYLCQCGC +>A0A674DTE1|unreviewed|Small ubiquitin-related modifier|taxID:8032 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGLY +>A0A8C2DU80|unreviewed|NFATC2-interacting protein|taxID:7962 +MRLTSPLSKAVEQLAIKLNVRPSQILLLNKDTDLPIHSSISELGLGIADIIDCVVTENKQEESDKSNVITVRLQGKEKAS +VQEFSLQKNAPLGSVLSQYVSGLAASARRKARFLFDGTRVTHNQTPADLDMEDGDVIEVWA +>A0A094H9K7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1420914 +MGVKISRAGGVLDDGGGAEGGDVHLEAWTREAFEAYKEAEETKARNAHLGLENDSGVGTAAAAEAAPSQPQPQEEKLRII +LRAKDMPEVKLRVKVTTKIADLVAAFRAQREAEVGGRSVELWFDGDRMEEDDCVGDADLEDLSGVDVVVR +>A0A1U8P3X8|unreviewed|Small ubiquitin-related modifier|taxID:3635 +MSGQQEEDKKPGDQSAAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEME +DGDEIDAMLHQTGGTV +>A0A6P6B2R0|unreviewed|Small ubiquitin-related modifier|taxID:66656 +MSATASVGGGGQEEDKKPADQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDMNSIAFLFDGRRLRGEQTP +DELEMEDGDEIDAMLHQTGGGCGSP +>A0A654G9H3|unreviewed|Ubiquitin-like domain-containing protein|taxID:3702 +MSTKSSSIHGRNEVKMEGEKRKDVESESTHVTLNVKGQNDEGVKVFRVRRKAKLLKLMELYAKMRGVEWNTFRFLSDDGS +RIREYHTADELELKDGDQIDALLPQQSGFGPSTVFRV +>A0A444XW73|unreviewed|Ubiquitin-like domain-containing protein|taxID:3818 +MTDDEFADELEPLFDYSRVQPPVISLDDEDDDADKDVVPPKKGKTSHDPVVPEKKQTDVKPVPVVDIDDEDDWLPPPPKV +STDAHKSIDEDSTLKKLRLKKQELQDLFKTVEESEKSEICDSPKSSMDDTSEKTSKPAERPKILISIQDKSEKKPVRVYR +DDKFERIFKMYAEKLGCDQNKIVLSFDGDKISPSETPDTLGMEDGDMIEVHVKSS +>A0A0V1AXM3|unreviewed|Ubiquitin-like domain-containing protein|taxID:6334 +LLIFVAYCDGFELKNCDHYFGSVYSVSNIMANDAESEANNVQSDFIQLRVVSQDSKEVTFRVKMDMPLIKLMKAYSERTG +IGLGSLRFVFDGSRLDDTKTPKELNMEDNDMIDVYQQQHGGSGLLVTCYAIVGAVVFRAIEFPLEQDIQGHMKNDSDHIL +QELLSYTKKQAVLNPREWMNLADSLLKDYETKLMHAVNFEGYDGEDEMVKYQWTYFGALLYSITVFTTIGYGHICPKTKL +GRAITILYAMIGIPLMLLCLANIADSLARLFTFIYSRVCCFYCRWKKRKSLMKKTSASVKYSSTIPKMKSPADIRGLLSP +QLRHVSTFPNESWQRMNRFGQAKSEKNVSNTYDDEQAESSDWKRKFSFKRKAAVDLPNNVVSGGRGRANTMQLPTIIISN +NNETHFHWNYTNEGDNDDDGDDDDEPLDSEGNVRVEKIHSDNDCCCNRLREMQVDFSRSVEDFIPSKPTRKAHAQLKYEK +VPVSVGILTVVFFIIGGAVLFAVWENWNVFDGAYFSFVTLTTIGFGDMVPGKSLDSGSEEKLIICSLYLLFGMALIAMCF +KLMQDDVVEKTRWLGERIGLLVRKESFGDESEFEDETCVDDLPTEVVEENPDLMITSQTQTENEQPTILPTKQQSYRIKL +HKPLGRTSSPHRPTQT +>A0A448YST4|unreviewed|Ubiquitin-like domain-containing protein|taxID:13370 +MSKRSISRAEDDFFAFGGDDDWDVPAVKKPKSERHRKSQHRHRHHKDRVSSSSGQGQTSSFSSSVTIELDSDGERGPKEG +GAAGGGAKGSGTEAGGAREGGESSKAADDNKNDDLIKLLGIESDVGVKKEAKQGAKREEKPEEPEEQINENVLPSPPSSA +TLPSDEQLLKQIDSEILQGSRHSDIDADLPLPASSTTVSFNGEDIKLKDVPFSIDVTCRLQDKECSAMVRVKGRTRFKNI +QEKMMNTLYPEGIPESFEATDSLVFYINELDMIVRQFLRVGTLLQISKTKIPLSEAGDAYHFHALMTTESVAQATKQLLN +MREWEPNYDQASAAADQEEITVSIRDRKDAASTKLAAKESTSIEELLSLYLMRKNYPDTLQLRLYDIDGKEIKKGSTVGE +SRIEDNDIIEVEYDDGELERLEKEEENDEDETTVVREEEGDPYFTINMVGKDRRSFKVQVNSETVMGTMADYYREKAGID +KKVKIRLIFDDEELDERAKVGDTELEEGFMVDVVLI +>A0A8J8VYN6|unreviewed|Ubiquitin-like domain-containing protein|taxID:2839758 +MSAEQEAGAAPSEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCDRQGKQISTVRFLFDGTRVRPEDTPDTLDMADGDTL +EVHQEQIGGGDF +>A0A199VLV4|unreviewed|Small ubiquitin-related modifier|taxID:4615 +MSGAGEEDKKPGDQSAHINLKVKGQDGNEVFFRIKRSTQMRKLMNAYCDRQSVDFNAIAFLFDGRRLRAEQTPDELEMED +GDEIDAMLHQTGGGPENA +>A0A1B9IY61|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1331196 +MSDKGKGKATNPISFDSDSDDDFFVSRRRPIIRETTAPRSPTPPIRTHSDSEDDDDASPDSQRKKKPRKAPLKKPTLDLP +AWTRQGSVGDKKNGSRSRKSSSQIRGSTEERADTIVIDDSDEEIGIVGGSSSKHMKKVTRKRVQLTPPPEMSEKSKADIV +KLVREHMSEKYGDQAPLENSASSPEKDRNDVEKVHVTIRMQAPPEKKQTAAPAAIKEYQKARTLILSRTGPMSTGISILS +ERIQKRPEDVILVYDDKRVYPRSTPAQLGILDKAEMIGYEKDYWMKLEADKIRALEEDLSFSNNNDDDEEGEDDVIPLNP +NGNSPSIFSKPSYTSQLQTRTQSQSQSQSLPQTQTQTQTQTQAQQDIIHFKISSSFGEERMKGPKTLKLHSVIRFYLKKL +GRPVDEADKWYIMFDGEKLDRSLRIEETEVEDGDMLEAGM +>C6T142|unreviewed|Small ubiquitin-related modifier|taxID:3847 +MSGVTNNNEEDKKPTEQGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELE +MEDGDEIDAMLHQTGGSVV +>A0A8C1JFZ4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:7962 +MSDEKAKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGTC +>A0A167N5K5|unreviewed|Ubiquitin-like domain-containing protein|taxID:1330018 +MASYDEEDEEFEQAQQEEQAPETQGRKKLRLTIQCQGQQCQVDVSATTLFGKVFDAAYKRFNKKKGTLRFLHDGQRIREN +QTPKMLEMEHEDVIDAELEQLGGTIW +>I3EDF4|unreviewed|Ubiquitin-like domain-containing protein|taxID:935791 +MHIQEVKEKDPKPTVQLKISDQSKKTYSFVMKRKTKLSKLFKEYTDRSHLDSHKLRFTHNGITVSGEETADSLGLKNDDV +LEVFSSQVGG +>A0A8D2CXD4|unreviewed|Small ubiquitin-related modifier|taxID:55149 +MSPKEGVKTENKDHINLKVAGQDGSVVQFKIKKHTPLSQLMKAYCERQGLSMRQIRFRFDGQPINETDTPAHLEMEDEDT +IDVFQQQTGGVY +>K2RJ68|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1126212 +MPDSASASGDAPPKQKRSFFKKPSWKQNVDNTDDDDPIAMFDRSKETFSAVMKEQERARLKRLQEQEEKARKKELKASKQ +GKRRKIDLDEECHSEEEGLNSARRDESKRSRSKSPTQDDVPAHSSQSPQPKFDANSLTARYETAARRRETAPKIATVIDL +GESDLEDGILPPVRDTVKQTTGPPAVDPDDDIDESDPELREIVRETRRKKRLEREQKAMQGTPPAGTEIRNGSSPGIARA +ESTPLTPPPQDPPVQILITSRIPGTKPLIVTRKLRQRLQEVRLAWCKRQGFDQEMIDSVFFTYKGRRLYDVATCRSLGLD +VDSYGNVYMKGNPDWDENDDKVMVEAVTQEIHQGNIREARRNREPEPEAKLAPELEQKRTRIIIKTKDYGEAKFFCGPDT +NFEKLAASSIVKLRIPAEKRPYLLFDGERLQPDGTMADLEDFEDGDALEMHFD +>A0A238C2S1|unreviewed|Ubiquitin-like domain-containing protein|taxID:387005 +MSQGEDTLGDDEDDYFDNPLKHLLSKVTSTRKSRNQTGTTTKDISKGESTKKDTSRRKTNVLDDLNNDGDDLLTLKGKRK +VKEDSVLSKVEQEIKELEIFSNISAFPSSSLNPLTSNPTKNHSKRKRKVTDDNNSKSSANPIIIDGGTVEADDNIFAKEV +FVVEPHCSIEIGDLEKCDICIKRWKMSETFTNIVKIYASNWSCSPDNVILSLRNGKRISAEDTPCSVAFSEKDVNYLSVY +KNGSQKANKITVKWLLPERNKPIITAVPKDIPFIILKRDFAVDNGLDEEKLTLVFDSERINLQETVSTLGIEDGDCIDVY +IK +>A0A284S486|unreviewed|Ubiquitin-like domain-containing protein|taxID:47428 +MSDEELQGGPSQDEIKGENNDPNAPINVKVVTSSGEEVFFKIKRSTKLSKLQGAYASKVGKDVATIRFLYDGNRIQEDDT +PQSLEMEDNDTIDVMVEPDLSYGVWTAHKDAELRFRRLRPYKSYFKKMHEIFTNQSTDFRYPNQQIYTPHGSRRSG +>A0A9W9B082|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:40482 +MNVHDGCFTFNHFVCVLSQVVGSSGEIVSFKINKHTPMGRALDEYAKKTGQERHTIRFRWAGVWISNTDTPGTLNMKNNE +IVNAINQYVERPSQSDSSSNSITTPSMDSPRSRDPSPSSLDLKREEEKEKRAVEEQKDAEEKARNLAEEKARTVAAKQAS +SIWGTLYIKATEDDQSPTHPEIVGVKRKRSESSVNSTVQDMELDKNYDELADEDNMINTEQRLAVIESKMGRVVDQQQEI +LNLLSNTYKKLKKVRSHGGALE +>A0A8B8J8T8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:42345 +MKRKKTADRTDGKVKESRKDVVVLDDDDEKGGKEREEEDWLPPSPQRIPSSGLALQEDKTLRELRLQKQELASLAQSAQD +VLRAVMESAKTELSSSGKPFPEVKASQPSKPQVERKKIIISIQGKDGQKQFRVYSDDKFERLFKMYAEKAQLKLENLVFC +FDGDKVSPAETPEGLGLENDDMLEVYVKSH +>A0A8H6S0S5|unreviewed|Ubiquitin-like domain-containing protein|taxID:2126181 +MSDEQQQDEPVKSEDAQGTINIKVVSSTGEEVFFKIKKSTKLSKLQGAYASKVGKDVGSIRFLYDGSRINDDDTPSTLEM +EDNDTIDVMVEQVGGAAVP +>A0A2N0RL48|unreviewed|Ubiquitin-like domain-containing protein|taxID:588596 +MTSNDQLLAQYIKSEAVDSNESTDSFINLKVRDYVKNQETVYKVKRTKPLNKLMQVHCDRNGLNIHVINFLFDGIRIKND +YTPDYLKMENDDCIDVVVHQRGC +>A0A4W3H8R7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:7868 +LSDPSDFCFYFRFPESKPPGNDSGDRKDGEYIKLKVIGQDNSEIHFKVKMTTQLKKLKESYCQRQLGMEDEDVIEVYQEQ +TGGKTSV +>A0A8D0AJG9|unreviewed|NFATC2-interacting protein|taxID:283035 +MFAGKENSDDVADDGLWSPFSSPKRSAAVVVGLSDSEDEVEHVEKKTEPAAMRCPSPPQSPVQKQSRQAQRKISEIDRKL +RAVNYLLSPEPQDRSCRSSRNSRSCNDDVIIMSPDDDGVMNPDSGLQDSPYSSLVREIPLKIRCRTDVHKIQVQSSTPLS +EVVTQLSGILSVPPPRLLLLREDVELPTHSTVGELGLGIADIIECVVMAAEDQRGDSSSSSSSRMTVRLQSKDRDSSQEF +SLHRDAPLGSVFSQYLSRMSPGSQKKVRFHFDGCKVTPGQTPAQLDMEDGDIIEVWI +>A0A9D3ZRV4|unreviewed|Small ubiquitin-related modifier|taxID:47602 +MTGVTNQEEDKKAADQTAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRGEQTPDELEM +EDGDEIDAMLHQTGGAMA +>A0A7M4DYR6|unreviewed|Small ubiquitin-related modifier|taxID:8502 +MSDQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGKKTVQLEMDK +>A0A3L8SFA1|unreviewed|Small ubiquitin-related modifier|taxID:44316 +MSDQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A8H2VNF6|unreviewed|Ubiquitin-like domain-containing protein|taxID:28548 +MADLDTEEAPPVKKKFSLFKKKLTQSPAPNIKPGQNHTDAFSRAKDLFPLHVKEKEIKREKKAVTLERKRSSQSREKSSS +SPRLEKRRKVGDVDVDVDVKVDLNDLGSETEDEELRARESSLSTPDSSKSQTRSPQQKRRSPTSLMGRFAKDVESKGNKS +GNCKAVTKGYISLSDSETEDIVPVRQTISRSSSPVVAPANSISVIDDDDEDAFSEEEFPELLAKARENKRLADLAQQRSN +AEWANRNHEPDRSAADDDVFQDKQKGELVLEIFISSRLENTKNLVIKRKLHQRLREVRQAWCDKQQWNGVPMPEELKDAI +LLTWRNKRLFDSMTCASLNLDFNTNGDLDSTGEGFNSGRIHMEAWTNDLWDECCKAASAEEISDDEEEPVEVVPEPIAKM +RLILKAQSKDIKEFKTYVRATTTVQKLVDGFRSMNRIPAEKKIILSFDGDQLDVESTVEESGFDDMDTVDVLIR +>H0EJK4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1104152 +MSDNEMSPEEEKPKIDNTILIRLKNQSAQESTFKIKPTTLFEKIINAYAKMHGKKVDTFRFFFDGHRLQATDTPKSLEMA +DAGTKSERQSRHSQLFPMLEYIAAL +>C3YBW9|unreviewed|Small ubiquitin-related modifier|taxID:7739 +MSDDNSDAKPAEGSGSGDQQYIKLKVMGQDNSEIHFKVKMTTQMRKLKESYCQRQGVPINSLRFLFDGQRINDDQTPKEL +EMTDNDIIEVYQEQTGGGEH +>A0AAD6EQE3|unreviewed|Small ubiquitin-related modifier|taxID:198213 +MVGRKDKGKKHDHRTHINLKVTSQFGKEMSFRIKHNTQLRKLMEAYCDDKSMDFQSIVFLFEGRRLRGSETPDELEMDDG +DEIDAMLHQHGGCFALPCRCTIELVSSFNLDFSIAKEHIANA +>A0A397YEB2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3711 +MRSKRCRAPQEKITLKVTNLEDEGKDVYEIGVHVHLERLMLDYCQRRNLDYTTLSFIFNGTFIRPLQTPAQLMMENDDII +DTVMD +>A0AAJ6RPH4|unreviewed|Small ubiquitin-related modifier 1|taxID:8478 +MSDQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A668TL46|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:47969 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGHC +>A0A7K7XJW1|unreviewed|Small ubiquitin-related modifier|taxID:874463 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0AA40FAE7|unreviewed|Ubiquitin-like domain-containing protein|taxID:314040 +MADNPEHNSPPQNDSAGATGAGSEHLNIKVTDNNNEVFFKIKRSTKLEKLMSAFCERQGKTLSSVRFLFEGQRVQPQDTP +DTLEMADGDTLEVHQEQVGGSR +>A0A6V7XSZ0|unreviewed|Small ubiquitin-related modifier|taxID:390850 +DSNEVHFRVKFGTSMGKLKKAYAERTGVAVNALRFLFDGRRVNDDDTPKSLEMEEDDVIEVYQEQLVACV +>A0A7S2QG93|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1333877 +MRELKGTGGGVDVHWHGGGSGYNHREVLHYDQGQKSPPIKSHQWPFPAFCARATASILSLTWNRRYRGQTIRGDAWEHVT +DRWSFDEFKCSGITRDAYRQAIEQVYREKACWIHALAFQTVMCYQFRHCRCPEDQISLCVYEKNIDCCRGAFADFLTEEG +LVDQYRGMIRPDHNGWTLQRMFDTWKQATPGPEPGVGAYVRLTGLTGNMSHLRMAGGVIRSIGETGVQVSLSEGEPGCPR +RGGNVYKCCAKQVQHERPLDMEFAEDSAPSPLSVCVKGKDISGFSGNLACFDIPHEIGGGRGAWVEWSKLEGANRCSSVS +PLFEKKQKVWHVLSDQKGDWTPLQKDINAADMYEAEWIEAARKTHFLMSVKPENVVLETEVYKLTIIPLDSSLGPGTVMC +TSTTPLRRVMDKYAKEFGLDASKVSFVYNDKFIRRHSTLKSLGVQDKRAHQGPVPRDWKARLGEMGSLKVANIEAVRKGF +KLTPPPTMKETDFEENELEEIEEYGGDDVGGENVGEEEIHEGKA +>A0A8C8JK29|unreviewed|Small ubiquitin-related modifier|taxID:74940 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSSHSEAPPTLSAWLCLD +>A0A815MTY4|unreviewed|Ubiquitin-like domain-containing protein|taxID:392033 +DQVSLTVVRKSDGQSMTFVLNEKTRIHDLKHELKRRLKPRFDRGCRLIFRNQVLKGKHTLKHYGIKKGVNDQAISMDDTK +DSKSSSSSSSSSDSE +>A0A1Y3BCN2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:6958 +MDNDEIDALFTKIDNLKRHPLLKHLKIKDQLAIPDIGQDCCWDLHLKRRIKEDILKIAHLHPSSSSSSSSSSSTKQGSAM +KATTDSQTVIRMNAASNVTGSQAAAEMNSELRIIIIDENWSQYCYRIKINTPFGKLINRFCQQVRKADNKSVLFWYHGRC +VEDDDTPRTLNIKDNEVILAHYIK +>A0A498IAK7|unreviewed|B box-type domain-containing protein|taxID:3750 +MKPMLLLSAGRLKFSRIKLNRKFAESDFGSAMEDFSEELEPLFDYRRVQPVNLIFLDDDELDAPSASPPKRREISDSAVE +KVDEPVKVVSVISCEDKEEEDWLPPPPKVSAGAKRKGEDSTIKELRKKKKELASYAQSAENVLRSVEESVIKELSILSEA +VEEQPPKPRPERNKIVVSIQDKDGVKQFRIYADDKFERLFKMYADNVKLDLQSLVFCFDGDKIGPAATPDALGMEENDII +EVHNWGSKVLKDRKMERFCEFCLALRPVVYCKADAAHLCLSCDAKVHSANTLFNRYMHSILCDSCRFRPAYIQCLDHKMF +MCCACESALHMIASQHQKMAINSYTDNTHLELDWTLSNSCGSSCDPSAVNLDSLEQSCSQAESLPAVNSVTWIPGAESEA +GSSSQQYKICHEGQEHNFILHQILDLKRLQLAEGNTPSLLIQRGSMFILIGVYNIPRIPTLNLGKGTV +>A0A3Q1GU03|unreviewed|Small ubiquitin-related modifier|taxID:80966 +MSDTETKPSSQDGGDKKDGDYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKEL +GMEDEDVIEVYQEQTGGLWND +>A0A150GKI3|unreviewed|Small ubiquitin-related modifier|taxID:33097 +MDAQSEIKEQPRFEDDCINLVVKDQHANEVRFKVNRHKTKMEKVFNAFYHKTGRDPGSLRFLFEGTRVNPQATPEQFGMD +DGDTIDAVEEQVGGTML +>A0A6F9B095|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:861768 +MSILLKDTKPSSQDGGDQKDGEYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQVIFPSHSQLIVRDR +>A0A0A0KWH7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3659 +MADSAEEFEPLFDYSRVQPPSVVCLDDEDSDADKSPAPFTKRAKIVNPAATSSVNGNPKEKQVEIEDKEEDWLPPPPKVL +VDAENRHVEDSTLKELRLKKQELASVALSAKNLLREVEESAKVDVGNTSMDPLEPDLDVQTPVASKERAKIVISVRDSDK +EELKQYRLFVDDKFERLFKLYADKLKIDPKSLVFVFDGDKVGPDDTPGGLGMEDDDMIEVNIKSS +>A0A8T2MBK7|unreviewed|Small ubiquitin-related modifier|taxID:7994 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGFI +>A0A8H8BUN8|unreviewed|Ubiquitin-like domain-containing protein|taxID:108018 +MSGSDDNGSPGAQEKPEAGASEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKAPNSVRFLFDGSRVQPTDSPDT +LDMADGDTLEVHQEQIGGGI +>A0A3Q7QCN4|unreviewed|Small ubiquitin-related modifier|taxID:34884 +MAEEKPKEEVTTENNNHIHLKVAGQDGSLVYFKIKRHTLLSKLMKAYCERQGLSVTQVRFRFDGHPIKETDTPALLEMQD +EDIIDVFQQQTGGVY +>A0A8T2P6Z1|unreviewed|Ubiquitin-like domain-containing protein|taxID:121402 +MNMVELRIFIPFVLVVVFSLTAVFAQTSAPEIKCEKKSNTSCEECLKQVECLWCKTTKKCINYPVKTILPPHSLCPLAEA +RWGLCWVNFQTLIITLSVIAGVIIIAVLVCCFCCCKCENIGSKRVEAKMERQADKRKTRQEESKEEDWERWERASQKIIY +KLSDPINKSALSDSMSEEKTKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPI +NETDTPAQLEMEDEDTIDVFQQQTGGSC +>A0A3P9AWJ1|unreviewed|Small ubiquitin-related modifier|taxID:106582 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGHC +>A0A067E3T2|unreviewed|Ubiquitin-like domain-containing protein|taxID:2711 +MLKPSSSKNNKKPQHLINLIIKSQDGDKRFFQFNHDVEIKRLLIKYCETKSQPFKSTPFLINGNRFDYSKTADQLGLKDG +DEIDAMYHAFGGGHDHRA +>A0A177C1F9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1460663 +MTDPTDGAAAPPKRRAFGFKKAAWQTAPKKDEQDMFSHSNEFQDIVAEQAKRQEEKKKAEEAQKQRQKAEEERHRKRRKV +SVESDEGVQARSSSRNHRVTSKGRSKTPMSPTRNNSTSETLAARYDSLTKSSSSSVGARTRSQVIDLGDTEDEDEYPRNP +SPSPRAIPIHSRPQSERESSEEVEEVDSPHIAVLKAQIRAKASAKSPDADQAPTASSSAQAPMPVAIVQLLIESDIPDTK +PLMVKIKTDASLAKPKEAWCTRQGFTPAQTRAIFMTWKGRRIFDYTKIQRLGIRLENGYVSVEGDPNIYDDENLPRIHVA +AWTEEVYKARKEADALEAAAAAQAAKVVNEPEPEAEPEPEVKQIKLVLKAKGREDFKLKVNPHTEVSHMASAYKMAMKIP +KEQPVTLMFDGDRLKPMDTVADIDVDDMDAIEVHFK +>A0AAF0EF26|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1381935 +MAGRPRPRVRKKQTSLDARTWKDNADDEFFIASRPRAGKIEMLMQPEAQETPTTAGLHDEDDCGRGRKRRKALSFDWVSQ +TESICSSSTVDGTASPDLKPSLPKTMERERSPSVSPPPPELEEEARTYALRAIEQVKQQHTSRMAALDVVFEGEEADPDT +SLELNADLAQYYKGRDAKQLRERALARELDRQEQAHVITLLEDEEEAQPVPVYEVDDSSEPEAPVAEPTFDRTAPLHEEV +HPDDTPSQVSDTLLLTMRGARQLEADVRVRPTTQMATLLEHFLSKHAQALSPEEKSHAYVSFEGERLAPTSQVQELDLEE +GDMLDVMW +>A0A9P6YTP9|unreviewed|Ubiquitin-like domain-containing protein|taxID:936053 +MSDEKQEKKEGTSSNEHINIKVVGSDKNEVFFKIKRSTQLRKLMDAYCERQGKAPGSVRFLYDGTRVLNHNTPNELDMDD +GDTIDVMVEQIGGY +>A0A0V1KPQ1|unreviewed|Ubiquitin-like domain-containing protein|taxID:6335 +MSATAHICNYFNNDILLIEIADPTRQWTVGFSLAASQINCDSLTAILPTFIHERVTNKTAADTDRANEIFPAENEDEDTE +ATEEYGSCVLHRGWQVARSVLVFTSSSILVSDCLIKYISIVCCFVVSMPSGKRETERKVNAPVNTGPSPNSDERVNNPTE +GADESARGSSPLHQAMANDSESESNNAQSDFIQLRVVSQDSKEVTFRVKIDMPLIKLMKAYSERTGIRLGSGFVFDGSRL +DDTKTPKELNMEDNDMIDVYQQQYGG +>A0A3Q3W8E9|unreviewed|Small ubiquitin-related modifier|taxID:94237 +VFTQTSLSLLRTEKESFSHQTVYKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQ +QTGGGWS +>A0A165E3K4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1353952 +MPSYDEDDEEFEQAQQEDSQPQKKTKIRLTIQCQGQQCQVDVSATTQLGKVFDAAYKRFNKKKGTLRFLHDGKRIREHET +PKMLEMENEDVIDAELEQLGGATW +>A0A0D2J480|unreviewed|Small ubiquitin-related modifier|taxID:145388 +MADDTTGETKPQPKQEGAVINLVVKDQSGAEVHFKVKTHTKLEKVINAYCAKKSIVPSTVRFVFDGTRVNPNSSPEDLGM +DDGDSIDVFQEQVGGRRP +>A0A6A5MM16|unreviewed|1-phosphatidylinositol 4-kinase|taxID:3870 +MTVADFALSSVHKEPVFLEGQQGQHCSSDPIMIYLNMDNAVTPMRVLESDSIASVKLRIQKCKGFVVKKQKLVYGGRELA +RNDTLIKDYGVTDGNVLHLVLKLSDLLFIVVRTASGKEFEFHIDRHRNVGYLKQRIRKKGEGFIDVDEDQELFRNGEKLD +DHRVFHDICKSDGDVIHLVITKSAKVRTTPIHQDLKLLVEASIQGERSIGQKVAKVPPDVGFWLEPIIVNPKIIFFPFLL +DMINSTFDGLKKGNRPIRSSEGTGGTYFMQNSTGQEHVSVFKPVDEEPMAVNNPRGLPSSTNGEGLKRGTKVGEGAFREV +AAYLLDHPKSGPRLVTGEALGFAGVPPTVMVQCLHEDFNHPNGYACSPKHVKIGSLQKFMNNDGNCEDIGPGAFPVEEVH +KITVFDIRMANADRHAGNILIRKEAGGQIKLIPIDHGYCLPDKFEDCTFDWLYWPQARQPYSPETVDYINSLDVEKDIEL +LKYYGWDVPLHCARTLRISTMLLKKGVERGLTPYAIGSIMCRENLNKKSVIEETICEAQDSMLPGTDEPTFLNTISKIMD +SRLDDFAKK +>A0A177A2M3|unreviewed|Ubiquitin-like domain-containing protein|taxID:655981 +MSTPDPSSPFASPFASPFASPTSAAPAPAPAPAPAVRKPLFKNRNRGGAAAATTTDAIGFFSRAKDVFAENVEVQRRERE +REREREREREREVQREMEVERVRELERARREKRERVVGGEVGGGEGGEEVDSENERRRKRSGSEDRSNTPAGESEYGDEE +APIEREGSTHPTYGNSVASPGPSQRNTRSQAQIISLSSDDEDDKPAPSPRPTYPSAFSSPPPKPVSTNPEPIAIPSSPPA +NPPSDDDELYADLIAAARRQPATTAAAPSNAPDPTLTILITSPLPNTTPLLIRRRLSQRLKDVRLAWCQRQPPHAGTAAT +SIFLTYRGLRVWDTSTCGSMGVKISRAGGVLDDGGGGEAGDVHLEAWTREAFEAYKAAEEAKARNAHLGLENDNNGISGG +SATETAPSQQQPQEEKLRIILRAKDMPEVKLRVKATTKIADLVAAFRAQREAEVGGRSVELWFDGDRMEEDDCVGDADLE +DLSGVDVVVRL +>A0A8C7T3A0|unreviewed|Small ubiquitin-related modifier|taxID:8022 +FASEFPEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGLY +>A0A438IL80|unreviewed|Ubiquitin-like domain-containing protein|taxID:29760 +MTNERPGKLSWAVRIAWALFEIVHVLENFQSVGGKEKQGAVLFELGFQRGSENDLDYWWEDGNEVFFRIKRSTQLKKLMN +AYCDRQSVDLNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTGGACV +>A0A550CPP7|unreviewed|Ubiquitin-like domain-containing protein|taxID:97359 +MSDEENQAGQQEDDQVKTEDPHAPINIKVVSSTGEEVFFKIKRSTKLSKLQGAYASKVGKDVSSIRFIYEGNRIHDDDTP +TSLDMEDNDTIDVMVEQVGGARRH +>A0AA39J667|unreviewed|HMG box domain-containing protein|taxID:1929756 +MSVFAASSHLTPPPKIEINDVQTLPDSSPITIKARYGFGRCVTLHSTLDQIAASTGYEHIFKLKTTTSLRKLFYVYAETI +GKEVDELKFIYEGQRLNPHNTPNTYEMENGDTIDVMLEYLLLAHNGTLALAPPASRTAAPVPSFAATQPYQIRGRRPRNP +STIFRDIFFATYKVLLPSNEAEVSRLASDAWHELSEEERLFYKTIAKLEKEAYELGKSTHALQRRGSTGDKGSKNDGGRR +MIPSLSVANLPYGSVAQGMDAQSFFYRTPTAAPEIPRIQYPPFFMTNTDTITHDVHATQGQGMTDVQHGRATQSMQTSQQ +WPPVPAAFAESSDSSDP +>A0A8C1E2F7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:630221 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQSSRLLALSLPHARFKVSSMSERVRERTMT +LMFTYSKERDTGSLFRSRSAHQKGTQAL +>A0A3M7MID7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1302712 +MFIVELDSHGSSDDVAQEATGISGVGRGFGRWAFAVGGHVDGGGGSPRSSHGHSAMTEPSASAAAPKRRALFKRPAWQDK +AQKEDDDIFRHASEFGDMVAEQARRRDEERKQKTQKTQKTQKTQKTQRHRKRRRTSNDAEPPTAPGGDNTTPLCPAPAHP +QHPSDSLSARYESLAKSTSSAEPLPLPEKDAHFVQLDDSDDDGPSGYSALDNTPQPPSRPTGNGAEDRPRQTGEAQDVAV +RSSIPHATDPDGGQDDEVEEIQDSLIAALEAKARARIAASTEVAVSTLAPIVHLFIEPQMDQATPLKVKVRIDNTIEKPR +TAWCALQAFSPNLTNSVFFTWRGTRLYDSTTIRRLGIQVDENGNVTVEGDSNIYDEVNLPKIHVQAWTEELFRERKKQDA +AAAAANKAPAMIEDKNPIAESAPIVTKIRLVLRAKGREDFKLTVNPDTTFAHIASAYKSKLNMDKNQAITLMFDGERLVP +LDTVVDYELEDRDEIDVLFN +>A0A8H2VGZ2|unreviewed|Ubiquitin-like domain-containing protein|taxID:61262 +MSDIPENNDTATPDVKPDVKADVKTETHLNLKVSDGSSEIFFKIKRTTPLRRLMEAFAKRQGKEMDSLRFLYDGIRIQAD +QTPDDLDMEDNDIIEAHREQIGGSN +>A0A2D0S404|unreviewed|Small ubiquitin-related modifier|taxID:7998 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGFV +>B4ND44|unreviewed|Small ubiquitin-related modifier|taxID:7260 +MSDEKKTETEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEV +YQQQTGGMDESF +>A0A8M1G644|unreviewed|NFATC2-interacting protein|taxID:29073 +MAEPVRKRGRRPRGGGVGRGGRGARGGRGRRPLVPRSPAPRTLDSEFVDLVSDSDEDILEVATARGAADSFEVPLPEPPV +PAAPRDDSDSDSEGADAPPAGAPRAPVRRRRRRLLDPGEAPVVPVYSGKVKSSLHLIPDHQSLLKLCPEEPEEDADVADS +SSPHAEDVPFPDSPWKKKLRSKDAEEKTKDVFLFQDTSPLPSPLPRTKSRKHTRALRKLREVSKRLQDLRSCLSPKQRQG +QDHQNQEDEVVLVEGPILPESPRLFPLKIRCRADVVRLPVRMSEPLQRVVDHMATHLGVSPSRILLLFGETELSPTATPR +TLKLGVADIIDCVVLASSPEASEMSRLLQLRVQGKEKHQSLEVSLSPDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLSG +KELPADLGMESGDLIEVWG +>A0A8S1FA49|unreviewed|Copper transport protein|taxID:2654633 +MMGMKMMMEMYFHFRVGEPILFREWTPKDNTGYVFSCIGIAAIAIVLEILKFGRTKLITSKPLKTTNVCNCSATDESWEI +PEIRRPLTVGSNSQSIVPFTKKSISDWKHIISSALFFAQNLIDYSLMLVAMTYNVPIFLSLLAGHTIGYFFVGPMMTFEE +TQNIIMADDAAAQAGGQANDNAEYIKIKVVGQDSNEVHFRVKFGTSMAKLKKSYADRTGVSVASLRFLFDGRRINDDDTP +KSLEMEDDDVIEVYQEQLGGGF +>A0A8B7AG24|unreviewed|Small ubiquitin-related modifier|taxID:1230840 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGMQAAGGLSGCGV +>A0A452TT81|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:29073 +IQNEKPEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>Q7PNJ2|unreviewed|Small ubiquitin-related modifier|taxID:7165 +MADEKKGSESEHINLKVLGQDNAVVQFKIKRHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTTLDMEEGDTIE +VYQQQTGGF +>A0A8B7BDZ8|unreviewed|Small ubiquitin-related modifier|taxID:1230840 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVF +>A0A7L0C7J8|unreviewed|Small ubiquitin-related modifier|taxID:252798 +QEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPISETDTPAQLEMEDEDTIDVF +QQQTGGAC +>A0A318Z1N0|unreviewed|Ubiquitin-like domain-containing protein|taxID:1450539 +MRSFFNKPSWASRGDETQDVQFYRHASQVYNDIISTNQDMRRAHQNQGTTSRKRHIPNENHGPDTLPSRVCKTHGRSSSC +QTPSESTASDCDLAQRGENTSSSQVPHPALRAAEGTDLHAIDRPMHSIVVKSQDKFVASDTLAAGCPSKSNRACIDVSQS +TNTLSPTEPPLTPSKQLIPSEEPFVQILITSTIYNTRPLIVRRRLHQPLRDVRLAWLDRQGLPKELENSIYLTWKGKRLF +DVTTCRSLGFGCKSQYLSRPNAYAVLQDDSKDLQIHIEATTGKSLDLDIGQSLSPAKLDQTADFTVVEQQFSKIVLMSPG +LKDLRLRVNLQMHVSKLICLFRDARQIPPEHEVHLVFDGERLESGCTLAEYNLADDDLLDVIVK +>A0A1I8B5C0|unreviewed|Ubiquitin-like domain-containing protein|taxID:6305 +MPDIISLFSDSSSDDDFYDNFDKIKLKAAHCQKKRKQTIAESTNKLRRKNTASGSVIPFPDEEIVCVEDFVSSSNFSTNN +PIPAVIEINGDFVIGYFIFFEFLAPSCSKSIEIIDLTPYGSSLTTNCSSKNSKAQKTENIPPPLKSTCTITINSNGGTRM +FIQDLDDPIKNLIEEYAERVNGDPKRIVLITKQLKQCALEDTPRTLGIISGEDFELDAFEHTDVVPLNSMDGVKTIRIKY +QQKGKRPIVAKILKTAKFARLKEIFCQENGLSLNKVQFIFDSVRVGDNETAETLDLEDDDCIDVYILE +>A0A1J5X8A1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1866961 +MNTSHGDETIVEVVSNNKEKESREDLDNFFLQNCTPENSPARKRVKADEREDSSDVLEEVVLVEKRNIPAKEKTAKKSPK +KRKRRLIIKLKEKTVLSGMFLPDETIGEILNKIPLLNKDGYFLSWNKNKIYSANTLEMLGIKTGSVLDLKKEGEERKETE +ETPQTNRIPPGFLILALRHKTERATMEFETNTKIGEVIARFNTEKKKECRKMLFDGEVLDKEKTITECELEDEDLVELL +>A0A9W8X3T8|unreviewed|Ubiquitin-like domain-containing protein|taxID:749621 +MATPLSTELVDDCVVVNSDLEISFHRTVRVPDNHQISHLPPYLGTFPLKPVSDHFETLPIEMVTKGGLFFPMYQSEAMWI +NFSCNGRQSYMIKIYVGGINIVSGEPAVEDGSTRLRRQALLANSGATMLTGKDSMGGIQIEVTPSPPRSLPDTVPSSGSN +YPDGTIQILIKDLSADYIYFKIKKTTQIGRLMNAACVRQGYNISSVRFLYQATLIGPTDTPETLGMKHGDIIEIQRKLIV +GGLDPLWQMAMAAGGRIRRHIAKDEHTGCSDVCV +>A0A7S0A5V0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:73915 +PSTDGSSGGSSLRNLHPDSIPYPCCAAIMMRCAVCLLLAGVVHGLDDDGCLAQASLRVHDSPQQQEHSGPVATQEAEAED +AQQQRKQELKDAKYGEQMTLLMRDVLGREFGIQFRRSTPLRILMGSVCKRLGLEQSQAFFTHNGTQLNGDETPEAIGLVD +QDIIVVDGKALQEEKAAQDKRERKAALAAQAKAEREAEEAEMMAKKEKKRMQVAKEAAKVQAQQKRQHM +>A0A6J3R1E7|unreviewed|Small ubiquitin-related modifier|taxID:9739 +MADEKPKEGVKTDNNDHINLKVAGQDRSVVQFKIKSHTPLSKLLKAYCERQGMSMRQIRFQFDGQPINETDTPAQLEMEA +EDTIDVFQQLTGGVC +>A0A7M7G8N8|unreviewed|Small ubiquitin-related modifier|taxID:7425 +MGDNQEQKPDSGPGDVNSEYIKLKVVGNDSNEIHFRVKMTTQMGKLKKSYSDRVGVPMTSLRFLFDGKRINDDETPKQLE +MENDDVIEVYQEQTGGNSWWSQ +>A0A7L1DUM5|unreviewed|Small ubiquitin-related modifier|taxID:279966 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A851EF40|unreviewed|Small ubiquitin-related modifier|taxID:85069 +PQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTID +VFQQQTGGVY +>C1BT33|unreviewed|Small ubiquitin-related modifier|taxID:72036 +MSENKDETEYIKLKVVGQDSNEIHFRVKMSTQMGKLKKSYSERVGVPLSSLRFLFDGRRINDDETPKALEMEQDDVIEVY +QEQSGGGKRPFHPF +>A0A0R3WJ45|unreviewed|Ubiquitin-like domain-containing protein|taxID:6205 +MLIKVCRTGRERQIVRVSDNVTVLALKKAIQRQLKIPIAEQNLTFNGLILEDNKLLSEYGLFDNCIVLLFLRLGFKPDFE +VTILLPTRKKLILDVSGENTIGELKKLIEKKIGLKLTSAELIYDHWVLEDGRKLIEYDITSGSTILLAHELRSGSSLELR +DSTHTRHTQIMPEPMSSCRLHQKCELAVNANSIDETDREDEEEDLKNLITVIFLAKTGSPIALRVHPSTPLGEVRGKLAR +VLHIPSNSMLFVRDGKSLDPAKTFAQYDISHGESVCLLSEAHVAENSCFWYSSEEESNEPKIRIIVQSKSGQTLACHVRG +STKIGSLKRRLEREVGVPRAKMGLFYQQKLLSDEALVSDYELSDGALIYLRY +>A0AA41SQZ3|unreviewed|Small ubiquitin-related modifier|taxID:30640 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A9W7ADL6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1714387 +MSSSDSDSSDSYTFTNTASVKFVSKKKVPPPSDSDSDSDSSDSSTFRSKKNTKKPQPQEQESHTTKEKDIDLVEVDDSFD +FDNCASSTPKKKTAALSKAKAIREKLAAAQTNTLIELDSDSDVEVTSPPSTSKNITTLSSSSLPESYATIKLRLNNSQVV +PLKINTTLRISSEVTKYITSTHSGTSIKIVFDGDEILAETCQTLDVEDDDQFDVTFTSTEIPRLKIKTTLNGKDYKTWSL +KISDNFEKLYEAAGKHYGGVVELTFDGDVINGSSCLEDLDMEEDDVIEVKLVSSKKKLVQGESHIGNGRGGSLRVGVVLG +AVVGALREHILADGGLAQHVSNLRSVDVSPCSD +>A0A9Q8T219|unreviewed|Ubiquitin-like domain-containing protein|taxID:145971 +MADAAKPKRRLPFKPTALRQKSDPKPATQKNDNEEEDDDDDGLSLFKRSAEFFPVAVAEQERRMKRKQAEREKSTQARSP +ERETEPAPRASEEPGKTDVEGETREPGTPPSKRSRTSDESPQSRTRQSPYKRREGTETPSKRLTRAAASRTPRKQEVIPH +KPVIAIEDSDEDLDDVDDVASDDIYEASPVRKTQRRRQTSEPEVSPLMIDSDDPFVEGMDKDKRSSVAGAAAAPEEEEDD +EFEEYVRRAMERKKALEQDENQLVNVFVTSDIPGTRDRQFRFTLAKPLKVIRMKWIEVQLERIEIPRSEVESVFLTWRGH +ELYDTTTLHSLDLEATFRKNGGGGGGGDGGADLSEGFKDDDWTNVHLQIWTRELWEEHEKQEARRRRHDLGDYSDDEGGE +QGDGADAIEPEVEQKIKVLLKTKTDEPLKTSVRPSTTIGTLMELFRKMRGLAEDAPITLMFDGDELGEETTVEEADIGDM +ETIEVYIR +>A0A1L0D242|unreviewed|Ubiquitin-like domain-containing protein|taxID:56406 +MSEEQKPDIKPAATDADHVSIKVTDGDSDIHFKIKKGATLKKLMDAWAKRQGKDVSALVFTFEGITLTPEHTPEDLAMEN +NDIIEVYRHQSGGYAY +>A0A100INN0|unreviewed|Ubiquitin-like domain-containing protein|taxID:5061 +MRSFFKKPSWASRGDEGTDPNFYRHAGQVYNDIITANRKARASRLSVVQEPKEEPEQEPEQEPEQESEHTNSKRRRLSCR +QPSAESSLGALTHNEALHNAEQPLDYNASYEHLQETNNNGDSCGPSAGVSSCGITVGITTETDDQCCESLPDVELTQVGT +IRAHSEVTKAVKENKIASVQQSRFENAREVDETVKPHNHSLAHNQAIVQILITSKIPNTKPLIVRRKMNQPLKDVRLAWC +NRQKFTKEMQESVFLTWKGKRLFDVTTCRSLGIHAKSGNFNGHDTFHLDVEDIQVHMEASTEDLLNADLSHSQTVTDAKS +SPEYTSWNGATSSPDRILLKCPGFGDLKVELNLEMQVSELVATFRAARQIPATRDIQLVFDGDRLDNNAYLADYELMNSD +LVEVIIK +>A0A7K8XCR8|unreviewed|Small ubiquitin-related modifier|taxID:91767 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>C0NKA5|unreviewed|Ubiquitin-like domain-containing protein|taxID:447093 +MDQAPQENQATAPPATGHLNIKVTDNNNEVFFKIKRTTQLKKLMEAFCTRQGKDLSSVRFLFDGTRVRQDDTPDTLDMAD +GDTLEVHQEQIGGYLP +>A0A6G0ZPW7|unreviewed|Ubiquitin-like domain-containing protein|taxID:307492 +MSDEETPNTEPSTSETTNVATSSTDKATEDDQQGHSTSVADPNTGALEVPEDKSLANADEYIRLRVITSDMTNEVHFRVK +AATALVRLKRSYCSKLGFQVDELRFVFDGHRITDDDTPKSLGMINDDVIEIYQERTGGTYVI +>W2T289|unreviewed|Small ubiquitin-related modifier|taxID:51031 +MADNGSEAPAAGDAGVEYIKLKVVGQDSNEVHFRVKNGTAMGKLKKSYADRTGVAVSSLRFLFDGRRINDDDTPKTLEME +EDDVIEVYQEQLGGCL +>A0A1T3CER2|unreviewed|Ubiquitin-like domain-containing protein|taxID:1491466 +MSENDQNQSPGDGQAPPPNTEHLNIKVTDNNNEVFFKIKRSTKLEKLMTAFCERQGKSLNSVRFLFDGTRVQPTDTPDAL +EMADGDTLEVHQEQVGGRLRG +>A0A498SA33|unreviewed|Ubiquitin-like domain-containing protein|taxID:6277 +MSREKEDDTDDDEEDFFGNPLKHLMSKVMNVKKNGNETGTTASDIRKKEPTKKDKGKKEDTLDDLKDDDDDLLTIGGKRK +VKEDSALSEVEKEIKELEIFSNTSAFPSSDLGPATSSSTKDETKRRRKVTDDGDSKSLDSLIIIDDSTLEADDNIFTKDE +VFIVEPHCSIEIGDLENCDTCIKRWKMNESFTNIIKLYASNWSCSPENVILSLRNGRRVSAEDTPRSIAFSEKDVNYLSI +YKNSQSGTHKITIKWLLPEQNKPIITAVPRDTPFIVLKRDFAVDNGLNEKKLTLVFDGKRINPQETVNTVGIEDGDCIDV +YMK +>A0A329SKZ9|unreviewed|Ubiquitin-like domain-containing protein|taxID:29920 +MSDEAAPNTNINNEEDKKKAEAITIRVKDQSGEETFFKVKPNTKMDKIFSAYAQRKGVPASALRFLLDGTRISGDQTPKM +LELEDQDQIDCALEQVGGFRC +>A0A317WX68|unreviewed|Ubiquitin-like domain-containing protein|taxID:1448321 +MADSGAPAGDAPAAVEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCDRQGKQASTVRFLFDGTRVRPEDTPDTLEMADG +DTLEVHQEQIGG +>A0A8D3CE51|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:52904 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGSIL +>A0A813GWA6|unreviewed|Ubiquitin-like domain-containing protein|taxID:89957 +MAETAEAAAQHIQLKVKDQQGSEVQFKIKKSTPLRKLMDAYCSRLGLQASQVRFMVDGERIAADDTAEKLGLEDEDLIDV +AMEQTGGNL +>A0A2H9P990|unreviewed|Ubiquitin-like domain-containing protein|taxID:1974411 +MVAEFNITVVQTTSGKEIVMAVEPEFTVSSVLEVLTENLKLKDRFVLSTKENKILDPDATIADAGLKEGDQIMLIPDPTG +G +>A0A2V1E2W9|unreviewed|Ubiquitin-like domain-containing protein|taxID:97972 +MSDNGSPQQQKPEDGQSEHLNIKVTDNNNEVFFKIKRTTKLEKLMNAFCDRQGKNISSVRFLYDGQRVQPTDNPETLDMM +DGDTLEVHQEQIGGC +>A0A553I958|unreviewed|Ubiquitin-like domain-containing protein|taxID:2512241 +MRAIPTWVEGPYLVAELTWAERKISAGTFNLVLLSTFLLSSSLLHTTSYTLLRPVGASHQNLRQLVPLGTGSVNVIHVTM +ADLQKPKRALPFKRTARPKLSSDASAPADDDGLALFSQSKNYFPTVIEDQQRRAREKAEKEEQERKEKLAREKEEKDRQA +REAQLRREQRRRPAEEGAEARDSTKKRRHSFLSDDENTIHEVEDDDIFVDKQPKLYRPSTPPSTATGRDASVPGSSRGAA +NARAARTPRKHEEPVILLDSSDDEDPTKRGSKAFITSRTRSGTSPIEEKRTSIDKGKAKADDSSSDLEIWENKQGKKEGA +EGEEEEDPSEFYIKAAMERMRKAKEARLARESSAAGNGDKNKSGTPSIDDDRGVPVSVMIAAPALPDAKALCCTVRTAQA +LQIAFDTFKERQKRQTAYPHQIISDLVFTWRGDRVYHTTKLETLGICPRGADGRLHDSASSGRSAPEGYVGRDKVYFEAW +TPEDYEENQQKRERERKRQEMGEWWNEDETANDDNGGGQAGAADAEVETSQKEDDRVRVIFKARDMPPRNVTLRKYSTVA +HMIKAFRKLAGLGEDKHVEIRWDGEALDLETTVEEADIADMDSVEVHIR +>A0A835NPN9|unreviewed|Small ubiquitin-related modifier|taxID:245042 +MAEHIDLKVAGQDGSVVHFRIKRHSPLSRLMKAYCSRQGLLLKHIIFLFDGQPIKEADTPAQLEMEHEDMIEVYQQQT +>A0A4P1QSF8|unreviewed|1-phosphatidylinositol 4-kinase|taxID:3871 +MTVADFALSSVHKESVFLEGQQGQHCSSDPIMIYLNMDNAVTPMRVLESDSIASVKLRIQKCKGFVVKKQKLVYCGRELA +RNDTLIKDYGVTDGNVLHLVLKLSDLLFIVVRTASGKEFEFHIDRHRNVGYLKQRIRKKGEGFIDLDEDQELFRNGEKLD +DHRVFHDICKSDGDVIHLVITKSAKVRTTPIHQDLKLSVEAPIQGERSIGQKVAKVPPDVRFWLEPIIVNPKIIFFPFLW +DMINSTFDGLMKGNRPIRSSEGTGGTYFMQDSTGHEHVSVFKPVDEEPMAVNNPRGLPSSSNGEGLKRGTKVGEGAFREV +AAYLLDHPKSGPRLVTGEALGFAGVPPTVMVQCLHEEFNHPDGYACSPKHVKIGSLQKFMNNDGNCEDIGPGAFPVEEVH +KITVLDIRMANADRHAGNILIRKEAGGQIKLIPIDHGYCLPDKFEDCTFDWLYWPQARQPYSRETVDYINSLDVEKDIEL +LKYYGWDVPLQCIRTLRISTMLLKKGIERGLTPYAIGSIMCRENLNKKSLIEEIVCEAQDSMLPGMDEPTFLKTISKIMD +SRLDKLAKK +>A0A182RQB5|unreviewed|Ubiquitin-like domain-containing protein|taxID:62324 +MSDIFGNLDNFLENYDENNISSSSNLSYTGSGIANDALVNDHSRRQSTNSATKSNKTTKSKRGTVPSQNNRNKTATTLGN +LAVTTSTNSSVLTPSTPAPAPSVIDLTPTTLLSIADEMQLLFQSFQSIFNSKNPIVQEMLKNREASAIKRSFSTLNNSYN +RKPPVTASEVMKLSKKIESVRNNLTQLDQKIKSTLEPVSPDQPSPSGRSRNTTAVNQLGPPNVISLDCDDDPVPMQTNAL +FGSRRVTRRSRASASTEGGSQSNVITLDSDEDSLPDCVGQQLNSSNRANNSFETENYIMRIKVKWRRGIEMFEHRRFQKF +GDIIDQLAKKESADSTCIFLNLDDRIVYPNDTPDSINYKSNQFISGRILRTKAPDLPTALVPSSSNNNCITLKIQMETRK +KPLRLQIDKHQTMSVLVIKCAEELKCEPKDIKMYFDGELVDNSSKPEDLDLEGEEILDIRFSK +>A0A7U2QRB0|unreviewed|Ubiquitin-like domain-containing protein|taxID:332952 +MAVGKTPISCDTRKNQRRAAIHTDQHSDSMKYDPVVQILITSKIESTKPLIVHRKMSQSLRDVRLAWCNCQSIPKEMQSS +ILLTWKGRRLFDVTTCRSLGISVPKGLADSPVHGDHVRYGSKEDIRIHMEAVIENNVMAMDNWQASHESYFASAQESTAT +DGSSRLLSTRVVLKCPRSGDMELNVNPRMQISRLVTIFRDAKKIPENREVYLVFDGDRLDPCSCLSMHDMADGDLVDVVV +K +>A0A8H6W536|unreviewed|Ubiquitin-like domain-containing protein|taxID:658473 +MADEQGGSQEEVKAEETNGTINIKVVSSTGEEIFFKIKKNTNLRKLRGAYASKVGKDVGTIRFLYDGERINEDDTPNSLE +MEDDGASPPPQKRVASALTPPNALDTIDVMVEQIGGVLP +>A0A1J9QSR1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1447872 +MDQQPPQENQAAAAPTEHLNIKVTDNNNEVFFKIKRTTQLKKLMEAFCSRQGKDISSVRFLFDGTRVRQDDTPDTLDMAD +GDTLEVHQEQIGG +>A0A0N7KUA3|unreviewed|Os12g0587100 protein|taxID:39947 +MLLMGDVDVNEADPEGNTALHWCLSGSSSTQEPRIVWLLLKNGARVFQGNKLGLTPVHSAAAKGNYKALQSLLLHAQDCV +DTPSKTKETPLFLAVKNGSLDCVKLLLRSGASTKVQNLRKQRPIDVATSQDMRFILTSANVAPSLLGLKHQQAIGISGLV +MVLPRGGKSKSHCAPKQGSKFVPRPNHWLKHDYTRKIFVGGLPPSVGAEYLTEFFTAEFGPMEEAVVIGIRMGDRVQSRG +FGFVKFKREEDVISAKETHHVYMLGKRVEVKDAVARGSLPSEIQKTSSFRHHNQEVPKVTHHLLGGELKEEHYIRKRRPL +PEKCLPSWFFIFRKWLPGFLADATERLGDRYPLSSLKGDFRAICRMELDHSTLGYPKLSDFMRSLPGICRMCVVPVGSGP +ATHKVLLPPVSRPKYVPLLVPFSFDHDELPESVSDHQFPMSPLTTNITEDSPRNTDSQHGDTCSESNAESQQDSASTDNG +SQLYTSIEPVSTRKLDVVEPLPARTPDRVEPQKIGSDPARKTISLESGLGVQIFIGNGSANLSLQVDVKKDVEYMLMLYQ +KRTGISSRNIYFVYRGKRLRLNRSLLSYGVQKDSTVNVRSRILGGAGTSLEEYLHKHKNSLVKKTALYDGRFFPELTPRS +SILLRTWVLCFTKAFKERHCWEPKCELSHFKVINGHVKVSTPAKGNLTTHFLQENLSFLAKTLKDFFRTIGTNLVSEYPP +YFEYFMKFILKIDLPCVPHLQKVIIELNLCFMDSYMRGVLTVRLKQKFDSLPPKQRATLIDKINHITWDTSRMPNLSTIP +VFDKIIKKAKDDGEPYFIENSVNFEFKAFNGFRLSRDAPIHAPQHRFDKTSVPWKENFPDNTIELMTPAYLGDLLPEIIW +CFILNKVDITEELSQSQTPCCTMCHPIKTDVGEYPTTQQTTVQDKQPTMEDVGSSSSMQQNVWKKIW +>A0A9W4TV33|unreviewed|Ubiquitin-like domain-containing protein|taxID:1227364 +MSDNESTPPIVNNNNNNNNNNSSSSSNLPQESESGNAGVKDEKPDTTHINLKVSDGSAEIFFKIKRNTPLRRLMEAFCKR +QGKDMNALRFLSEGQRILAEQTPNDLDLEDGDTIEAHRAQTGGR +>A0A8H3BVQ8|unreviewed|Ubiquitin-like domain-containing protein|taxID:456999 +MADATPSQDAKMMITITHSKGAAPDVKVAVKKVSQLRKVFVAAAERFRTTPDALVFKYNGQVLEGDHTPKMHEIPEGGVI +TAYPADEEDASTQDLQNTQVSMDRFGGDAMDQDEPSPSAKNDKITSKRYVVLTQKVAFQIKVARVKPLKAAFDKAHEQFK +KAPNTFRFFYNGTRLKDDDTPKMHEMENNDEIDANIQQVGGAFLA +>A0A087XCA8|unreviewed|Small ubiquitin-related modifier|taxID:48698 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMED +EDTIDVFQQQTGGSAL +>A0A1H6PM24|unreviewed|Ubiquitin-like domain-containing protein|taxID:4952 +MSEETQPKVDSSEHVNIKVTDSSSEIFFKIKKSTQLKKLIDAFCQRQGKQKSSLRFLYDGQRVTDTDTPETLQIEDGDTI +EAHQEQLGGC +>G7PCJ1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9541 +MADEKLKERFKTKNNDGINLRVAGHDGSVVQFKMKMKRYTPLSKLMKAYCERQGLSTRQIRFQFYRQPIDETDTSAHLEM +GYEDTTDMF +>A0A428PRR9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1325737 +MADKGAASPPIVKKKLPFKPTALRRLAAPKPTPTPTQHDEKEEDVKDSDDDGLALFRRSKEMAPIVAADRERRLKRHQKH +QMDVERRTREAAREKRPREESEEVVNQDEPVVSDEIGPDVAGSQSSPVRPRSSHVAEQPPATQDITDRASELVTPPPSKR +SRLSSSSSSKKPIPALELDDDCDGEPFPDASPTPFQRKPSTPSRAPRMARPPPPPMNVISIDSDSDSDVVSLKPSSVPAS +RRSTSIVELVDRTSSRQSPKEPSPPPEDDEFAEYVRKAKERRDRDQALLQTGLDGKPKKEFVDILITSQVPGTRPLKLKY +LFDKPFRLTRETWSSYQNKSGLSIPVDDVILTWRKKKIYNTSTLLSLGIRPQGDGRVIAEGQGSEGFEDNRSLVHVEAWT +PELFQEMERNEELRRRREAGDISEEEEDQEEETTEDVKLKVMLKSRDLEDLGLTIRPETTVETLITCFRAQRKVDPNKQI +GLWWDGDRLEEHVTMEEAEIEDMDTLEVYIQ +>A0A2N5T0M5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:200324 +MSTSLLVIKLSVKEPLLFDQAAVDSYSHQTWPGFNDGKLYTGHHGRNNPDARLDRPSSSKSRASATDRLPSAQCDRIHLS +AAKEVKPGRLPELEICWNANGYINLNITYTNNQLGFSATSNHSTDDVLLTLRGGQTRQTTQNYPQGPIPIPGCTIGINPY +SYLPNWNHNRLQLSSDGKEPLFLKVKRTTAFQKIYKAVTNHLQVTPHSFRLSHDGERLNPDETTPDDLNFDDEEVLDHFL +EGVGGSFDGQDSLKQNMAASEDRMLDSGNKNNLISIIINSQQENLGVQHRTKRAGFQQQQQQHQHVDIE +>A0A7K9XQ42|unreviewed|Small ubiquitin-related modifier|taxID:54359 +QEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDV +FQQQTGGVY +>A0A8C1EZ49|unreviewed|Small ubiquitin-related modifier|taxID:7962 +MSDTETKPSSDGGEKKDGEYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNSLRFLFEGQRIADNQTPKELG +MEDEDVIEVYQEQTGGCRND +>A0A8C0CNU0|unreviewed|Small ubiquitin-related modifier|taxID:9771 +MSDQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGRSTI +>A0A3M7GWP8|unreviewed|Ubiquitin-like domain-containing protein|taxID:91943 +MASEPVEEMPYTEQPSPQQPTTPAQQEQLTPKFRDMGGFSIDFKLKPVTKLGKAMDAFSARLQKDTKELRFLSEGRRVLP +DQTPLSLELEDGDEIDVHMEQIGGHMI +>A0A7K8KPS2|unreviewed|Small ubiquitin-related modifier|taxID:89386 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A0V1IAD6|unreviewed|Small ubiquitin-related modifier|taxID:6337 +LLIFVAYCDGFELKYCGLRIEMANNTRDDTEPESNNVQSDFIQLRVVSQDSKEVTFRVKMDMPLIKLMKAYSERTGIGLG +SLRFVFDGSRLDDTKTPKELNMEDNDMIDVYQQQHGG +>A0A2L2TI74|unreviewed|Ubiquitin-like domain-containing protein|taxID:56646 +MSDENANGTPGEQAAPNSEHLNIKVTDNNNEVFFKIKRTTKLEKLMTAFCERQGKTTSSVRFLFDGTRVQPTDTPDALEM +QDGDTLEVHQEQVGGSSL +>A0A7J6G471|unreviewed|Ubiquitin-like domain-containing protein|taxID:3483 +MSVLGQKRKCMDQEEENCDDDQRVSIKVVSQGTANKETYFKINKKCRLFKLLQTFCNHQNVDYRDMQFLFNGKRISPKHT +PHSLKMKDDDQIDAMMHTDGGGSGCDRGGNNAF +>A0A023FTQ3|unreviewed|Small ubiquitin-related modifier|taxID:251391 +MAGSGQDPKPEGPDSSEYIKLKVVGQDGNEIHFKVKMTTQMGKLKKSYSERVAMSVASLRFLFDGKRISDDETPKQLEMV +NDDVIEVYQEQTGGSQVPAALSGQDRRPAS +>A0A7K5JVG2|unreviewed|Small ubiquitin-related modifier|taxID:254557 +FTLQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A4W3HR83|unreviewed|Small ubiquitin-related modifier|taxID:7868 +MYNLADHTIYTEQIYARFTVFCNLANAKLVSYLKTNQDLKNEGNDHINLKVAGQDGSVVQFKIKKHTPLSKLMKAYCERQ +GLQIRQIRFRFDGQPINETDTPAMLEMEDEDTIDVFQQQTGGTC +>Q6FY59|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:284593 +MDFSDEDSDEFFMGTSEDVEERLQQAMASRAPQAPNAEPAPVQEPHAEAEAELEPEAEGPSQEQVRGQDVVVIEGDTEGS +GSEGSSDSEGSSDSGAQDTYRGDKEYEVRTRSGMKRARTVEDENDLFFQSIAKRSQSLPVQDGSGAVRQDKVYYVQFISH +VDGTKGKSVQVKALGSHPFSKLVAAALSGLMRAHRLPSVMRPLYQPESVVSYWNRAKVLGFMTCDTLRVPQRYGSDYLEI +QLVPVKEEAQYLEQEVFEEPERAPTPEEDAEEEFERELRDAKEVRAPVVDLESEEVLRVALQGQDNKKVYVNVKPTTTFA +RMIEYYRTQKQLPRSTQITLALDDEPLDPHATVKSQDIEDEDMLEVRLS +>Q8I444|unreviewed|Ubiquitin-like domain-containing protein|taxID:36329 +MGDDDSAVNNNGSSPVNNQGEHIQVKVRSPDGAEVFFKIKRKTKLEKLMEVYCNRLGQSMEAVRFLYDGDRIHGDNTPEQ +LGIEDGDVIDAMVQQTGGSF +>A0A819RYM1|unreviewed|Ubiquitin-like domain-containing protein|taxID:2762512 +MKIFIRTNTGRGRPYEFNVELTTTVKELKQLTRKKTNDDEDALKNMFFTFDEDILDENDETLASYGVEEESELELRYSNI +KGRNLGALGTRFADVNNSKGLKRCAWSQTAPRWRRTRHGLCLEGTCSNTECEAHDHNVIIPVGYKKFDILCDPDDTTTVC +PVCKNFVQPTNCGFNNCWWKFQGIKQEGDDNRKAPKRCSSEWTQADNAYHYFDQLTSGTVTWKQLVLEAVKNKPAS +>A0A5D1ZZ14|unreviewed|Small ubiquitin-related modifier|taxID:34276 +MSGVTNQEEDKKPADQTAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRVEQTPDELEM +EEGDEIDAMLHQTGGAMA +>A0A7L4RF75|unreviewed|Ubiquitin-like domain-containing protein|taxID:2250274 +MGEFTIKVVHTTSGKEVKLAVEPSFTVNSVLEVLADSLQLKDRFVLATSDNKILDPNITLADAGLTDGSELLLMPDPTGG +>A0AAD8L1C5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:13708 +MSRANNNQGADITLTVNGQDGIEMIFRVKRSTPLKKLLNTYCFRHFVRPNCVTFTFLGCLFQRDQTPDELEMKEGDCIRA +FFHQNEKQKVFFDEQIAKDNVREEEYATFVVNKLQRIIWRIISKLIAENVCLKEELTRLTKVNKVEDKDVALWKIGRFVN +KSFRENSGPREELKKEVTRLRDELKEDLKEEIATLLKELAECEDEDEDDDDEDEDDEGFIDDGKFVSELIAWAKKNQDFV +RCMLSKL +>C4YCR9|unreviewed|Ubiquitin-like domain-containing protein|taxID:294748 +MSDTENTGGSPPAAEAGPKEEKGTHINVKVSDGTQEVFFKVKRNTKFRRLMEAFAKRQGTSPDTMRFLVDGGRVHADQTP +EDLDMDDGDTIEAHRAQIGGCL +>Q69WJ6|unreviewed|Ubiquitin-like domain-containing protein|taxID:39947 +MSTTSPRAEEDAKETVKPIFITLKVMDQEDRRIRHTIRMADKLQVVMDMYYAKAPDVTYGTGTFLFDGIRLKGDMTPMGL +EMVDGDTVDFFPVMIGGGGFFQCNLLPSSH +>A0A8I2Z9F7|unreviewed|Ubiquitin-like domain-containing protein|taxID:100787 +MIPWSSKLPLIKPIQTHRLISSPNHRPRYAEAVEHLNIKVTDNNNEVFFKIKKSTKLEKLMNAFCDRQGKAFNTVRFVFE +GQRVQPTDTPSALEMADGDTLEVYQEQVGGC +>A0A9W9V430|unreviewed|Ubiquitin-like domain-containing protein|taxID:293559 +MSDKEGAAPPTEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKQISTVRFLFDGTRVRPEDSPETLDMADGDTLE +VHQEQIGGC +>A5DSR4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:379508 +MSSNDLSTPKTEENTSAGHSTSSKSAQGTQRKRKLVFDDDFFCLGGSFLQKKKAGVPHPKSTTALNHQPSNSPEYTSKRD +PNNLRKLELNQSKDSHQNKSNDNQVVLKSDSVDEIEEIITKVEPTKTEKVSHELQQEKSYLPLFQKLHQHQHQHQQHQRQ +RQLLLPLRVSSFDKELLKREIELKLDAVKDTKEKTLLEDSDEEYYEPAKTSSTSLLRSETPPLQTDLYDFDMTSERKRKY +IIRVSSKLPVPEGLTVQVDLGCKGLKSFDKILQSAVDFFRKTYARQLPPILLQRYNYEESALVWVEGKTLIHSFFTPRTL +RIPLPGGLFNPALEKIEDVPPTMMLVFLIPKESSTNFLHVYPEFTTPTDNFIMNETAAEEQVVEAEEEDLSSEEDDVPHD +VLESQNTATNVNTNPSHPSNSNSNSNSNSNSNIADDGVFAIGLKGKDNKRIMCNVTPATKLQNILLFYLNSKGLDPKGPA +ALRAKLIFDDEELDLKLSVRDTELEEDFEIQVVV +>A0A8C1PH08|unreviewed|Small ubiquitin-related modifier|taxID:7962 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGHSSAGG +>A0A2K5IVX1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:336983 +LHSSPSTFGFIEKLYYRFFCRSWCCLCARSVRTWYLFCEMAAEETTALPTADEKPTEGVKTENNDHINLKVAGQGSSAVH +FKIKRHTPLSKLMKAYYTPAQLEMEDEDIIDVFQQQIGGVY +>A0A317UMW8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1448314 +MRSFFKKPSWASRGDEGTDPNFYRHAGQVYNDIITANRKARASRMSVLQEPEQEPEQESEQESEHTNSKRRRLSCRQPSA +ESSLGAPTHDEALHNAEQPLDYNASYEHLQETNNNGDSCGPSAGVSSCGITVGITTETDDQFCESLPDVELTQVGAIRAH +SEVTKAVKENKIASVQQSRFQNAREVDETVRPHNHSLAHNQAIVQILITSKIPNTKPLIVRRKMNQPLKDVRLAWCNRQK +FTKEMQESIFLTWKGKRLFDVTTCRSLGIHAKSGNFNGHDTFHLDVEDIQVHMEASTEELLNADLSHSQTVTDAKSSPEY +TSWNGATSSPDRILLKCPGFGDLKVELNLEMQVSELVATFRGARQIPATRDIQLVFDGDRLDNNAYLADYELMNSDLVEV +IIK +>A0A5J5QWE5|unreviewed|Small ubiquitin-related modifier|taxID:3634 +MSGAQEEDKKPGDQSAAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEME +DGDEIDAMLHQTGGTSA +>A0A3P6SX16|unreviewed|Ubiquitin-like domain-containing protein|taxID:42156 +MWIKANQSCVSMMPQDAADDNDEDDFFGNPLKHLMSKVTTAKKSGNETQTTTRDRIKKKDKGVEKESTLDDLNDDDDDLL +MLGGKRKIKEDSALSKVEQEIKELEIFSNISAFPACSGLSMSHSAKNNIERKRKVVDNSNSKPPEPDSPIIIDDCTLESD +CNIFVKDEVFIMEPHCSIEIGDLESCDTCIKRWKMSETFTNIIKLYASNWSCPPENVILSLRNGKRISAEDTPHSVAFSE +KDVNYLSVYKYSQHRSHKTSKITVKWLLPEQKPIITAIPKDIPFTVLKRDFAANNGLDEEKLTLVFDGDRIKLQETADTL +GIEDDDCIDVYMK +>A0A0V1GYT2|unreviewed|Ubiquitin-like domain-containing protein|taxID:268475 +MSCTYDSDNDFEGFYEQMLKRVRNEAVTVDSDDEPLSDIVSKRQRLHESDDEENLRKLKVILMYHGMSDDPKEKTLELSK +NEPLRVVYKYASEQLKISQRKIEVLYNNISVMPKDTLEKLNIKEQYTFLDIKLKCAENSPKKSTEKKVTRTLESTLEMRC +CTSREISVSHDVAESPVSTNFTLKLLHQNRQYRKELKVNRQDTFGNIKCRYSEAIGISISRIVFSVDGDQVQDDMTPQSF +ELEEGDIVDVCIL +>A0A8S2B330|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:38785 +MSTTRSDITDDGNFDGGDEGGVTDQEEKKFVLQISFGNDVRYFRMKRKCLLSRLMKLYCESKNLDFENVIFLYNGRRLRP +ELTPDDVDMENGAAIEAILVRSM +>D8QVL5|unreviewed|Small ubiquitin-related modifier|taxID:88036 +MEGSSETPDVKPEKKPGDHMNLKVKSQDGNEICFSIRRNTRLAKLMKAYCERMSVAPDSIAFLLDGKRLREDQTPEELEM +EDGDEIDAMLHQTGGMPLL +>A0A8H3PHP7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1903189 +MSDRDQSPSAGGNPDDQPKSEHLNIKVTDNNNEVFFKIKRTTALSKLMNAFCERQGKAPSSVRFLFDGARVNPADSPDSL +EMADGDTLEVHQEQIGGA +>A0A109FHB4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1305733 +MSDNGGENNEVKPEGPQHVALKLQGSGFPELVIKVKRTTKLSKMMNAYCDRAGKSLNEVRFMYEGDRLKGDMLVSDLDID +DVDADEEVVIDVAQEAVGGASL +>G1TRW5|unreviewed|Ubiquitin-like domain-containing protein|taxID:9986 +VPGCAHLPVTVPGCSHSPSPPWGAPPPCHSPRVLPVPVTAPGCSPSPSRSRGAPPLPLGPRVHPSPSQPQGAPPLPLGPR +VLPSSRPGVGPFLSRPEGCPGSGRQSLGRWRRKLRSLSTCWGPGAPCWGPGAPAAAGVRGEQPPSQEGVKTENDHINLKV +AGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMDDEDTIDVFQQQTGGVSSRLPGRG +LFSILAFAVE +>A0A670JCA9|unreviewed|Ubiquitin-like domain-containing protein|taxID:64176 +LKCFCCGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTGGVY +>A0A0V0U8N0|unreviewed|Ubiquitin-like domain-containing protein|taxID:144512 +MLLATVFLPVPQVDTGVSLLEAGTTGWMTDERLPHWNVRDVSLRTNSHLEGWHNRLNRKADKSHNGFYELLELLIAEQGV +MDTLIQHVLSVNVTVGELRRAMANDAESEANNAQSDFIQLRVVSQDSKEVTFRVKMDMPLIKLMKAYSERTGIGLGSGFV +FDGSRLDDTKTPKELNMEDNDIIDVYQQQHSG +>A0A0N4ZDS2|unreviewed|Small ubiquitin-related modifier|taxID:131310 +MSDNERTSEHNNATTSGGAENEDEFIKLRVMGQASNEVHFKVKKSTTMAKLKKTYADRMGVNSASLRFLFDGKRIENTDT +PKSLEMDQDDVIEVYTEQVGGTC +>A0A8T0RY08|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:38727 +MAPVGAGGGGGCGGRRGAGAALLLQAGAAHHRLPLRRYASGPLLRGLGFRPGESLQGLVGFGVQTATWRRRTSSSTATNA +AATEEEGKPDEKAATAKAVDVDVDWLLPPPPKAAFKPSAEEDNALRELRLKRQELAKWAESVHDILQDLDATARTEVVSK +EQPEQIIIDDEPEPQVEKVREKIVISIQDKNARQQFRVFKDEKFDKLLKVYAKKAKLNPSDLAFVFDGEKVNLSSTPEDL +DLEDDDMIEVRHKRHCGLGALQVALISAVLGKLRYLLLSKVRCPYPYTKDM +>A0A8B8W4I0|unreviewed|Small ubiquitin-related modifier|taxID:9771 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A8C5VSZ5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:30608 +LGREKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCEPQDTPAQLEMEDEDTIDVFQQQTGGKKLVGH +GGACL +>A0A8D1N8U4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9823 +SRPQPSRLREAPPPVFPPRLSSFPYPSPQRVAEVTRGVAEVPPAAVLCCGEERRICKPRSEVLPTRGRCCAETPGEVTVT +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQLGMEEEDVIEVYQEQTGGHSTV +>A0A2K5RQD6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2715852 +MADEKPKEGVKTENNDHTNLKVAGQDGSVVQLKIKRHTPLSKLMKAYCERQGLSMRQIRFQFDGQPINETDTPQTGGARG +PDLCIPTLTSHWIWSAPGALGEEIPFT +>A0A0V0SSV4|unreviewed|Small ubiquitin-related modifier|taxID:144512 +MANDAKSEAINAQSDFIQLRVVSQDGKEVTFTVNMDVPLIKLLKTYSERTGIGLGSRFVFDGSRLDDTKTPKELNMGDND +IIDVYQQQHSG +>A0A8C6NS96|unreviewed|Small ubiquitin-related modifier|taxID:105023 +SEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDV +FQQQTGGLI +>A0A1A8AI98|unreviewed|Small ubiquitin-related modifier|taxID:105023 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKEL +GMEDEDVIEVYQEQTGGFWND +>A0A2Y9I2E8|unreviewed|Small ubiquitin-related modifier 1|taxID:29088 +MTTHLKKLKESYCQRQGVPTNSLRFLFEGQRMADNHTEKELGMEEEDVIEVYQE +>A0A166H7M1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314672 +MARTKTSGSKPQTQSAPVLDALVVEYNQRKVAIRRVADYPAILIAIKRSVRALAQVATEDIVIKCNTLPELEGEYVDISE +DAWPDLVFRSYLKKVVVEVDTPVPKPVSLAPSNARAHRSNLQEARISLPSFSVTLSSFSGEEFYVSVRADTSIRTLRKFL +ARKCHGCEERYNISYDGSRTHDHETMGHLGIEEGDRIDWMYELVGGKPVIYLSPPESGPSIDATVELSLSASWSLSALYP +INPDSTRVNSSYGQHTIWTVRAGPDGVLYDKATEAEVSYLYWEATTNPPHPISPPASPRSTPTLAEFDPSRAQLSARDSV +LLPVDKVPAYLDRALTALTLHTEARTSFITYWLPSLLKHEYVALRFVPQLEYDQAARLIVTPEPDVVTRVFMVFRGVDEK +EMFEWAPAIGRSGENVAFWGDVVGIDANVALNPSLFRVLEWGGMEVFTR +>A0A8X7U8X3|unreviewed|Ubiquitin-like domain-containing protein|taxID:52824 +MMRSSSTSFTSKRCRAPQEKVILKVTNLEDEGIDVYKMGTHVHLKKLMLAYCQRRNLDHRTLRFIFNGSFLRPRQTPAQL +MMEDDDIIHTVMEQASNAGPNDDA +>A0A165VSL7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314782 +MSDHEEQQATQDPVPKVEDANAPINIKVVTSAGEEVFFKIKRNTKLSKLQAAYAAKVGKDVSSIRFLYDGQRINEEDTPA +SLDMEDNDTIDVMVEQVGGSA +>A0AA86VST0|unreviewed|Small ubiquitin-related modifier|taxID:92480 +MSGVTNNNNNEEDKKPSEQGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDE +LEMEDGDEIDAMLHQTGGSVF +>A0A423WJK2|unreviewed|Ubiquitin-like domain-containing protein|taxID:1230097 +MSPYRQEDRPPTGQQRPEAPARPEQLTVKVTDNNNNETLFKVKRSTKLGKLMVYFCERQGKVLDSVRFLLDGKRVQPTDT +PDTLEMEDGDTLEVHQEQQGGSG +>A0A7K9ELR3|unreviewed|Small ubiquitin-related modifier|taxID:176943 +PQQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGVY +>A0A1Y2H8W1|unreviewed|Ubiquitin-like domain-containing protein|taxID:765915 +MCLAIGLWIHHDPDGANAQDAANRARRRQNTVDLYKARFGPDMDARVWDMGLELPKLPSAAANKTGLELSDRINLRLRDI +TGSEMEFNVRSSAPFDKIVKAYADKKGAMMEDFRFDFDGTLLWKGEWKDRESRTVNDLELVHGDVIEVSASQVGC +>A0A8K0R8B2|unreviewed|Ubiquitin-like domain-containing protein|taxID:798071 +MSDNGSPNVQQKPEDAGQSEHLNIKVTDNNNEVFFKIKRTTALGKLMNAFCDRQGKNISSVRFLFDGQRVTPQDNPDTLD +MQDGDTLEVHQEQIGGSW +>A0A484GTH9|unreviewed|NFATC2-interacting protein|taxID:103600 +MAEPVRKKGRRPRGGGVGRGARGSRGGRGRRPGAQRSPARRTLDSVLVDLVSDSDEDVLEVATARGAADPAEVPLPEPPV +PAAPRDDSDSDSEGADARPAETPRVLVRRRRQLLLDPEEAPAVPVYSEKVKSSLHLIPDHKSLLKFCPPETEEEADMADS +SSLHAEDSPRPNSPWKKKLRSRDGEEKKEMLLVQDTSPLPPRLPRTNSRKHARALQKLREVNKRLQDLRSCLSPKQPQGQ +DHLSQEDEVVLLEGPTLPENPRLLPLKIQCRADLIRLPVRMSEPLQSVVDHMAGRLGVSPSRILLLFGETELSPTATPRT +LKLGVADIIDCVVLASSPDVTEKSHLLQLRVQGKEKHQLLEVSLPRDSPLKTLMSRYEEAMGLSGRKLSFFFDGTKLSGK +ELPADLGMESGDLIEVWS +>A0A8S2A8J7|unreviewed|Purple acid phosphatase|taxID:38785 +MRQRLEARKLLVDKTSIACKVTEQDVKKKEDNLSTEVRSLLVGGTTLSIAKSKLQESNCQLEGESGYAHLKIVTNKLRKR +QQFMISQVSFIYPLKIEAGPSQDQELESFPGGSRLGTKPLSQGSVRILGLPFSMAPFTRMSFFTDKKEVQKSATALGYVA +HAVSLIAPYLRVPIRYPLRLGGSKTYIRDYAPYIEPSPSDMSPITTLSQNSNFVEFPLFLDGQDTTRAAYAVFLLNKNIE +QLLNFVGENSLGPRQRSRSPETPHQKITLKVKNQQGAEDLYKIGAHAHLKKLMSAYCMKRNLEYGSVRFVYNGREIKARQ +TPAQLKMEEEDEICSVMELGGGVYYLLRCNTHLCKNLKMVVKCTMSMSFFVIFASTVTVIVHGFPSTLDCPLNPVTAPLD +PNLNPIAFDLPESDPSFVKPNPEFLPQQISVSLSYSFDSVWISWVTGEYQIGEEDSAPLDPNCVQSVVQYREFDVRSTIN +KNATGHSIVYTQQYPSEYPSENGLKNYTSGIIHHVQLTGLKPNTLYRYRCGDLSLSAMSKEYYFRTMPKSTSENYPHRIV +VAGDLGLTYNTSIVLTKILSNHPDLVVLIGGFSYADTYLANNTKLDCSSCHCDQNGTSSDCGSCYLSRETYQPRWDYWGR +FMEPLTANVPTMMVAGEHEIESQTDNNLTFAAYSSRFAFPSNESGSFSPLYYSFNAGGAHFIVLNSYTPYDNSSDQYIWL +ESDLSIINRSETPWVVATWSLPWYSTFQGHYKEAESMRINLEDLLYSYRVDIIFNSQVDAYERSNRVYNYTLDQCGPVYI +TTGAGGAGKLETQHVDDPGNCPDPSQNYSCRSSGFNFTLEPVNNETCPVKQPEYSAYRESSFGFGMLEVS +>A0A8X7R1G0|unreviewed|Ubiquitin-like domain-containing protein|taxID:52824 +MVNGRDIPITLDELHEKLVEREHTLLTTGVSSSASSSSTHVTVSVKGQDEEEHRVFRMRRNDKMSKVMERYNDARGAELG +TYVFLSEGGSMINKDKTPDEMEIKDGYQIDAMLHQHGGFGPSSIKF +>A0A0G2DY62|unreviewed|Ubiquitin-like domain-containing protein|taxID:420778 +MSDNGSPKQDAGQSEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKSPASVRFLFDGQRVNATDNPETLEMQDGD +TLEVHQEQIGGAC +>A0A9P0J3X1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:80765 +MDVHRAQDATEYMNLKILGHDNSVTPFKIKKHALLIKCLKTYFKIIGLDRVSVIFSFDGHRIIKTDTPSSLEMKEGDVIE +VFLRQIGG +>A0A1A8RXQ2|unreviewed|Small ubiquitin-related modifier|taxID:451742 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKEL +GMEDEDVIEVYQEQTGGFWND +>A0A7L3MI26|unreviewed|Small ubiquitin-related modifier|taxID:2585811 +LFLQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A9W8ICJ3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2650707 +MANYISDSDVEEVVSPAPSRLKPRVVRRPVPVRTQSATSGQDSTFAGAISDSDSSDADDDDFFRLNRAPSATEEESEKAA +TLGNSPGTTPRQLSTDNNIVSLENSDSDAEAEEQDSIKHSTSAKRRHDSEQNGEQERRVRSRSVSLTPPPEAARVNGGAE +SERLETDHKEPVESFVLESESETEEQSRAAEDFGTSDLDPALQAVIQSEAMTPSRGGSVGPANQLASPQPYANSPATRTH +HNAVLEKVQIEFRFIFDPEFLASELPCIWEQKRWGRIKSTSAKTIEKKLNGQIAIIAFTSELVANVLKAYSDAFYIDVLA +TDPVLMNGTMRVFPTSTVASLGSDLAFYIKVFPRSVYNRWHEQEILEKTQLAMEQEQARRDMENALQKHTASGIGLPDLD +GTDVQESGTAATAGGIRIKVRDRAGKDTLLLVTTETSVETVIKNYRQLAKLPETTRIQLEFDDEVLNPSDTIGDTEIEDD +DMLTAIWK +>A0A8T0GSU9|unreviewed|Small ubiquitin-related modifier|taxID:3225 +MAGVEDASTPGTQQDEKKPLDGAGGQHINLKVKGQDGGEVFFRIKSSATLRKLMNAYCDRQSVDPSSIAFLFDGRRLRAE +QTPAELDMEDGDEIDAMLHQTGGASF +>A0A8J5ZSC1|unreviewed|G protein-coupled receptor 150|taxID:202257 +MEEPLGPPALSPAPNLSVPISLDWALNVTSSAQEARVPGAPPPPEPPPEPPSRRVRLVFLVVILVVAVAGNTTVLCRLCG +GGGPWMGPKRRKMDFLLVQLALADLYACGGTVLSQLAWELLGEPRRAVGDLACGFVQLLQVSGRGASAHLVVLIALERQR +SVRGPRHPPLPARALAGLGWLLALLLALPPAFVVRGGVPSPPPAATPAVRTWFQEHSCRGIFTSLPRWHLQIYALYEAVV +GFVAPVAVLGIACSRLLRAWWQRPPEAPSAEAPWSAQAASNALPRAKVQSLKMSLVLALLFVGCELPYFAARLAAACSSG +PVGDWETGYLAVTLRLVGVVNSALNPFVYLFFQAGDCQLRRQLRRRLGTVCCATEGVTEDEEGARGHQALHRHRWPQPHY +HHARREQPEENCLRPPPPRPRTWYLFCEAAAEETPALAMADEKPKEGVKTENNDHVNLKGLSMRQIRFRFDGQPINETDT +PAQLEMEDEDTIDVFQQQTGGVY +>A0A8C9I160|unreviewed|Small ubiquitin-related modifier|taxID:591936 +MANEKPKKGVKTENNDHIKLKVVGQDASVVQFKIKRHTLLSKLKKAYCERQGLSMRPIRFRFDGQPINGTDTPAQLEMED +EDATDVFQQQVGAVY +>A0A671Q0Z1|unreviewed|Small ubiquitin-related modifier|taxID:1608454 +SIMILPSDSVVTPQSYFIHVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMEDED +TIDVFQQQTGGHI +>A0A4U0XV88|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:329884 +MSLFNRPAWATTQDAGAEASSENIFSHSKQSYAEIMAEERRAKKAREQKLRMKQERKERRSSAKREAEVEVEDSKAKGRA +SPKRRRITLEEGDDLLGSVGLPLGLVKRRYGGEGNATDGLPVRRSPRVNKIADRDDSRCAGERKAIRPMVVEVLDVSDQE +NEVQFSHARPAEPVEQESDDEFAELIREARARNKLREESIKKSQTPDLKSPTPGQDVAKLSRARYPTPPAPDPPVKLLIS +SRIEGTKPLMVFRKLSQRLQEIRHVWCDRQGFSKDFAEGVYLIHRMRRVFDVTTCRSLGLGVDAEGNVTMKGAEGAEGVD +QVHLEAVTDEIYAQIKAEKDKEERIRQGVDETEEEAQAGASETQAQPEEPIIRIYLTSKERRDPFKLKVKPSTPIWKIMT +ACRPQFDLREGQSIYLDFDGERLGSEQTVQDTEINDMDRIDVHVY +>A0A3B3Z1D1|unreviewed|Small ubiquitin-related modifier|taxID:48701 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGVY +>A0AA39NQW5|unreviewed|Ubiquitin-like domain-containing protein|taxID:1929756 +MSQEAEDIKPKININIQTDDGTKITVLVRRDTKFSKVFQAAEKKFGKEPGTFKFTYEGKRVQKDETPADVDMEDGDTIDA +HLGQVGGGHKW +>A0AAJ8KCM3|unreviewed|Uncharacterized protein|taxID:1296100 +MSASDSDSEPELLIEIQPTDGKAQMPFKVLPTTKFSKIFTAYEDRLNVDKGSYKYMYNGARIHRDGDSTPKMSEFKIGRQ +YVVEANLEQLGG +>A0A671EXY6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:59479 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>A0A443REP4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1965070 +MSSEEEDSDCGIFGKKRLNYRRKIKIATDAKIINSQLNANDSKEFSTFAELDNENKPSTESEEVIEISCLEEDTIKSATT +NDKDIFNDWKSPAKDEASDSHVDITFESTPSSIRGRRPNSRDQFSNRGSEADILDPELILQKLDEQANEICNDLNECFDT +CDDCIIEERGDPKTSHSLLSEIKFNFHGKIRKVQISSNEKIYNKLDMIAEQFKIDDPLSLAICFNNKLVSMDATPKSLNL +TVADILDCIIKQASFTSADNSHSSQYEKVSQIKDPNIVSIKFRNNKSSKNSKPITLNALKAKELQNVMLEYAEIVEIEVK +KLNFYFDGEKLNGNETPEDLEMEDGNLIDVVIKE +>A0A4W4DQZ3|unreviewed|Small ubiquitin-related modifier|taxID:8005 +MCVCVCVYIVNLQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINESDTPA +QLEMEDEDTIDVFQQQTGGFWGMLLAKAS +>A0A7K6YCW8|unreviewed|Small ubiquitin-related modifier|taxID:28689 +SVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDEDTIDVFQQQTGGAC +>A0A2B7WXR8|unreviewed|Ubiquitin-like domain-containing protein|taxID:2060905 +MDQLPQENQAPTAPPPTEHLNIKVTDNNNEVFFKIKRTTQLKKLMEAFCSRQGKDLSAVRFLFDGTRVRQDDTPDTLDMA +DGDTLEVHQEQIGG +>A0A9Q7XL50|unreviewed|Ubiquitin-like domain-containing protein|taxID:2043611 +MSDAEAPQPKPEGGEQLNIKVKDADGNEVFFKVKRTTKLSKLKKAYAERMGKPENSVRFIFDGQRIGDADTAESLGMEDQ +DEIDAMIEQLGGC +>A0A5N3XK55|unreviewed|Small ubiquitin-related modifier|taxID:9886 +EGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQ +QQTGGSRVASCLSGSGL +>A0A830D0K8|unreviewed|Ubiquitin-like domain-containing protein|taxID:374723 +MNAYCDRQSVDFSAIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTGGGAIA +>A0A671NN16|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1608454 +MSDEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGTC +>G4TPI3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1109443 +MSSERDVKPNIRDGDDNAVSQDPQTPMKKPNAKINLSVTSPNGQTIKFAVKPTNTFEKLFKASAERFGVELNLVRFLYDG +ERLRPEQTPQDFDMTDDDQIDMQLQQTGGGTGL +>A0A178UNS2|unreviewed|Small ubiquitin-related modifier|taxID:3702 +MSATPEEDKKPDQGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDG +DEIDAMLHQTGGGAKNGLKLFCF +>A0A068Y030|unreviewed|Small ubiquitin-related modifier|taxID:6211 +MGDDNAPKEKNNEPINLTVHGQDGSVIHFKIKRTTPFKKLMNAYCQRLGLTLSNVRFTCDGEHVQYEDTPESLDLHDNDT +IEVFQTQTGGI +>A0A833TRD4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:51240 +IPPKNSSPYSITAAFSFSISCASTVTCLHFLPFFPADDDDANASQALSSKRRKISEPIVVEDVEENPKVIHIVDSDKKEE +LDWLTPPPKVSTDIQKMIQEDPTIMNLRLKKQELVSFAQSAEDVLRAVEESAKRELGNSIQSSLKTVADQSSKPFGKRVK +IVISIQDKNGLKQFRMYMDDHFERLFKMYADKVKLDIQSLVFCFDGNKISPAETPDGLGMEDNDIIEVHVKPS +>A0A9P3BZV1|unreviewed|Ubiquitin-like domain-containing protein|taxID:75553 +MADNGTPSEAPAPVEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKQLSTVRFLFDGTRVRPEDTPDTLEMADGD +TLEVHQEQIGG +>A0A8J5FR70|unreviewed|Ubiquitin-like domain-containing protein|taxID:94328 +MSGQEEEKKPADQGAHINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDINSIAFLFDGRRLRGEQTPDELEMEEG +DEIDAMLHQTGGGLEV +>A0A1L9TIP8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1036612 +MPSYFNKPSWASRGDENGDSEFYRRAGQTYEDIVATKRNARERRESSPRSNTHKRRRLASSPNDGDIVRPNCEHATAEGN +ALLRNSSPPQNDSQHNTRSVKTAAHKPLVSNDSTITDTKGSISPRPQNSPETNLPDLRAELTSTRSDITDDGNLDTHPKN +CLVDTAVPTDTDTSCDARSTAYDNTVVQIFITSKIPKTKSLIIHRKMSQSLKGVRLAWCAHQNLPRELHSTVFLAWKGRR +LFDVTTCRSLNIGVHNAFTKELPPFENCFSDVDDCRIHMEAVTEQTFAGRSRPSPIIARFDTTPSAPTEPRGTDKYIQSE +IILKCPEFDEFKTRISLATHVSQVVEAFREARSIPTELTIYLTFDGDRLDPQCCLADYDIADGDLLDVLVKKEM +>A0A179F0K1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1380566 +MSDGAATPSQRTAKKLPFKATALRKVASLRAQIIIDEKELESDGLDLFRRSKEMEPIVAADQERRLNKKRRHDGQRRKSA +ESSASRFVDDVAEIYDMVKEKSRVSPQAAWSAVPVAREPVTQGGELSRLRVGHATGIEVIEADTPILNTFRPYTRQPTGR +PIAVPYGASIAPEPTKRRGSANSIQSSFIAGDEDDEFATYIRKAEEQRALDQALLGVGSDGAASKAKIDILVTSIVPDVK +PCCFKFLFDKELRLARNTWLALQKRKGVLLDVEREDDIVLTWRRKRVYAFSTLLNLGIRPQDNGRAVSDGNDAKGFANGR +TRVHMEAWTLDLFREMEREEELKRKGETTELADEEEPALVEEKPPALEVKTRVILKARDIADVKLTVRRTTTVETLITGF +RTQRSIGPDRDVQIWFDGDRLEEHATMDEAEIDDMDTFEVHVK +>A0A8D9EB76|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:428564 +MFQDWDSKSKSTDDHISLMVLNGDANGVQFKIRKETPLIKLMNAYCKTCNLDLNLLRFRFDGDCVSKLDTPKKMKMEDGD +VLEIFQEQEGSGLQSNLQTSKT +>A0A3M7AMI4|unreviewed|Ubiquitin-like domain-containing protein|taxID:91943 +MDPETVEQMPFTAPPPPQQPATPAQDQLTLKFRDMNGFSIDFKLKPITKLGKAMTAFSARLQKDTKELRFLSEGRRVLPD +QTPSDLELEDGDEIDVHMEQIGGHMI +>A0A8C6FTX9|unreviewed|Small ubiquitin-related modifier 1|taxID:68415 +MTTHLKKLKGSFCQRLDIPINSLRLLFEGQRIADNHSPKGLGIEEGVIEIYQEHTRGHSTI +>A0A2D2AP23|unreviewed|Small ubiquitin-related modifier|taxID:7959 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGHI +>A0A6J1U5T9|unreviewed|Small ubiquitin-related modifier|taxID:8663 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGMN +>A0A167FDZ0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:796027 +MTTPTNGTESPESAEERAAPVTTQPTTDPGPEKPKLSKWKQRRKLRPAAKKTPSVTESDSGFFSMAHRFSIDDDDDEPDD +KKTAVEESEIKPEATASMNKKVDKSLISKSIGSVESELSKLAGQSDISAQPTMLSDSRSILVNGNKTAREPGFEPQSMVS +FDTKPISKSRPATRAATTQAKKAADTVIILDDSDNTSSDIEIVEDSTPPDVSGAKRSVVDPTDDPFNTIQQLKLRALKRK +KVENVFEVSVNISSDMPELGNCRSTVMTMKSNEPFGVLKILYTKHCVENRLNYFEPKAIELLIETAVLVWNDTVLNEDVV +TPSSLGITNANSVMSINIMSRFDYDNKQKSSVERLLSEENYTLQAILASTSTQTDTRELQKPDNLGPAYFRVRLKDKDNA +QFEVRVNSETKISKLVDFYLRNKNLPQNTKIRLDFDEEPLDLDGVVGDTELEEDYTIHVYIL +>A0A453GBA0|unreviewed|Ubiquitin-like domain-containing protein|taxID:200361 +MNAYCDRQSVDMKAIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTGGCRLPPSA +>A0A6P8XTF9|unreviewed|Small ubiquitin-related modifier|taxID:7291 +MSEEKKAETEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEV +YQQQTGGGSFISQQQL +>A0A5C7I781|unreviewed|Small ubiquitin-related modifier|taxID:1000413 +MSDPTTVKKEAQEEKTTPSEYMTLRVKDKDHNALVFMVRKATPLKKLMDAYCVRKNVELNTFVFLFDGRHLRPEQTPDEA +GLGDGDEIDTFQHQMGG +>A0A2K5UM06|unreviewed|NFATC2-interacting protein|taxID:9541 +RCGPRGRGGWGGRGRRPRAQRSPSRGTLDVVSVDLVSDSDEEIVEVTSARCAADEVEVAPSEPPGPVASRDDSDSDSEGR +TRGPQDLPREPVRRRRRLVLDPGEAPLVPVYSGKVKSSLCLIPDDLSLLKLYPPGDEEEVELADSSGLYHEGSPSPGSPW +KTKLRTKDKEEKKKTEILDLDNSPLSPPSPRTKSRKHTRALKKLSEVNKRLQDLRSCLSPKPPQGQEQQGQEDEVVLVEG +PTLPETPRLFPLKIRCRADLVRLPLRMSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVL +ASSPEATETSRQLQLRVQGKEKHQTLEVSLSRDSPLKTLMSHYEEAMGLSGRKLSFFFDGTKLSGRELPADLGMESGDLI +EVWG +>A0A7S2TBJ8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1461544 +GEAGRGFFFFFFWRPCAFFHGVTGGRRRGGAAPACSPYEIAPATRVRRDMGNPIYAVPKSKSEFTHVYIQLRVRDQSGSD +VYFKMKRRLPLGLLQDAYCQREQLDLSKLCFLYKGRRIIPDETPEELDMEQVVTVDVVKLD +>A0A8H4D8I9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1231523 +MSEQPKEEKTDSTHINLKVSDGTAEIFFKIKKTTPMKRLMEAFCKRQGKSMESLRFLIDGTRVSPDNTPEDLDLEDGDVI +EAHREQVGGSR +>A0AAE0SWS3|unreviewed|Small ubiquitin-related modifier|taxID:2493646 +MSEEHKKDEKKDSEHINLKVSGQDGSVVLFKIKRHTPLRKLMQAYIDRTGAKKEQLRFRFDGSVINEDDTPAGLDMEDGD +AIDAFQAQTGGGSN +>A0A5N5SWJ1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:96803 +MEISVLSVLEGKASGYIVFRVSSDTYVGDLLKRFCKEKNVSVAKDYVLCGRGNATLDPHKTLKQEGIKDEDTLKLTQEDK +NEQLFAFGSWWVIALLAFLMGSIGITYCLYMFLFPQKLPQKYGLVIDAGSSHSQLFVFTWSKPEKKTMADIELIHGCYMH +GGVHNYRFHTDGLHHYFNTCINEANNLIPVSLIPRTPLILAATAGMRILRAYDPEGATLVLSSIREVFWSKTKFLINHKD +VFVASGQEEGISGWTALNYLMENFDEEDSQVSALDLGGASVQVTTELSKGFKHWPSVNITIFNNTYRVFSKSFLCYGVEE +AKHRYQYLLFSELVNNTHDNVIFSPCLPAGLEMSLTSEDFYSPCIFSNDTKIYLHPKYLSRYAKKYVSGYSSDSNNHIKD +MTKKRNYLLKGTSDMKLCQEKVKSLFDYELCKKNFVLGDCLNKKLVPPYKGELVGFSSIFHRLLPLLGVSQEGSLEEFRT +SVLSVCGKSKETVFELHPNISIDMLEDLCFDGMYVYTLLKEGLGITAKRWKNILFTNKVHEQDVVWAMGLMLNRTSTNLS +YVQSRKMGLVTFVALVTIFIFFIILSLLFLWYSLKLKQRGNIYQRVPMRIAEEA +>A0A9K3GUC8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:4232 +MYKIYTYIAEKVQVTEEVIGIDDDNDDLDWLASPKVAVKKGKQCENSVIKELRLKKQELLSFTESAKDIVQTIEETVKRD +LNTSLNSEFESPVEKPSKPAVERPKIVISIQDKEGLKQFQTYKDDRFERLFKMYVDKVKNKAENLVFCFDGDKVGPTATP +ISLELEDDDIIEVHVKSS +>A0A9W7HAL0|unreviewed|Small ubiquitin-related modifier|taxID:183268 +MSATGGGGGGAEEDKKPGDAAHINLKVKGQDGNEVFFRIKRGTQLRKLMNAYCDRQSVDSNSIAFLFDGRRLRGEQTPDE +LEMEDGDEIDAMLHQTGGGC +>A0A8D0FQC9|unreviewed|Small ubiquitin-related modifier|taxID:311401 +MFFLQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKE +LGMEEEDVIEVYQEQTGGHSTV +>A0A067MCG2|unreviewed|Ubiquitin-like domain-containing protein|taxID:930990 +MVTTQTNEEVFFKIKRSTKLSKPQGAYATNVGKDVSSIRFLYNGERINEDDTPASLYVADNDTIDVQVEQVGGGFS +>A0AA39CB63|unreviewed|Ubiquitin-like domain-containing protein|taxID:144406 +MSDNQEQKPEAGPGDANSEYIKLKVVGNDSNEIHFRVKMTTQMGKLKKSYSDRVGVPMTSLRFLFDGKRINDDETPKQLE +MENDDVIEVYQEQTGVILAKHQVNPFVATIGDIATVSNFANDALAFVNGELPLENLIMGSTGHAINTIIEKMDELSNTLN +EMEANNERRMNYMLETLISRIPQEIKVDTGLSKLHDLIVRVDKLFENYNYYSKNPESYDRSTIDNFINAVISHQKGDLSD +TLDNMHSLMMPGRSAKYQKPLLEILNQKTKMLSFGELCSAGTSPQQRLFEIYHAILLTEARAYIMNIFSYAMLTKYKNTS +FAGEMRKAAEQLVTRARGYLVSTKRAMKEASITLDYCDPNNFTRGENFVELEKSIQMFIVNEVDLNDNSCGNVCERSDSA +GLRSDARKCNGNNGNSWCPLQSCYGRIYDCISAGETSVCELSKSSLRRYDWVKDSNARSYGNTNSCDGRIKNPVDYTSGV +RLCDVCICTCADEIGDSPASRTINLRPQLSNIEANMVITGVKFISSDKIIHIQIKEGELMSGGRIKPETEHWVEPETFMY +DPTVGYYGRRVGSFFLTTGNTTKFMKQGKDFAFVNYFQRHVNLDDVKAPTDYVVTGVKFMREGNDTDGRSRRPLQLSIYV +TKFDFSKGILLKDSSYWICQENMPNRPKDYGRRPRNEVELSEPDDPTKGLDHKTVSEPGEMVAFRASDRAKDAGQATIPF +FDGQSITSTISTALSGLGLFHRGTTGSGGFLALRLLTLDLPEYVNTELTPEMIASFEPVN +>A0A8H8MD47|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:170446 +MSSSRPRPKPRPKPKTLPNAPVSSTSATSAGSSTPVKSSGATDDDDDLFIRHDPNRIAATYSQQKKARAHSPVPATQDVT +YFNNHDNSEDSPESKRRRKEQGGRSKPLPAWTYQTREVPSLPIETDSDSSGPEILDDIDQAPSQPLAKPKLRERSITPPP +DEIRYQASSQAQAILSNIYHDDEREVTPEGESQDVIELLPELAAIQRNARATSAAPELSDNRQVELHVKWIPHPEKPQHF +EQGEHSWTFQVPQNKPFSEVRRMLTGIQLTSLPVLRKGPKRLFDGGTPGSLFVGTKLEIQAMTLATHQYFEERHLDPSSA +PPGDDVDEEIAINSREGSPAATEEKISLKLRAGPKDNNPTTVRVLSNSTVGDVVAAFLNKIGRPGAQGVRLQNDGEDLDM +EATLADAELEDGDLVEVVGIQK +>A0A5N3VEM7|unreviewed|NFATC2-interacting protein|taxID:9888 +MAEPVRRRGCPRGGGVGRRARGSRGGRCRRPGAQRSPARRTLDSVLVDLVSDSDEDVLEVATARGAVAAAEVPLPESPVP +AASRDDSDSDSEGADAEPGGTPRVLVRRRRRLLLDPGEAPAVPVYSEKVKSSLHLIPDNVSLLKLCPPEAEEEADVEDAS +SPHTVDFPCPSSPWRKKLRSKDGEEKKKMLLAQDTSPLPSPLPRTKSKKHTQALRKLREVNKRLQDLRSCLSPKQSQGQD +HLSQEDEVVLVEEPTLPEHPRLLPLKIRCRADLVRLPIRMSEPLKSVVDHMAARLGVSPSRILLLFGETELSPTATPKTL +KLGVADIIDCVVLASSPEVAETSQLLQLRVQGKEKHQTLEVSLPHDSPLKILMSRYEEAMGLSGHKLSYFFDGTKLSGKE +LPADLGMESGDLIEVWG +>A0A9Y3QZC2|unreviewed|Small ubiquitin-related modifier|taxID:303518 +MEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVF +QQQTGGHC +>A0A1R3G5C2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:93759 +DDKFERLFNMYADKTKLELQSLVFSFDGDKISPADTPASLEMEDDDLIEVHVKKR +>A0A2G5C3F7|unreviewed|Small ubiquitin-related modifier|taxID:218851 +MSGTPPPPPSEQSQQQDEDKKPNDQSAAAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVEFNSIAFLFDGRRL +RADQTPDELEMEDGDEIDAMLHQTGGGLEGWCPC +>A0A1W7R7V2|unreviewed|Small ubiquitin-related modifier|taxID:7160 +MSEEKKDSKGSESEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTTLEMEEGD +TIEVYQQQTGGKLYF +>A0A1S3HRN8|unreviewed|Small ubiquitin-related modifier|taxID:7574 +MSEEQQLQNKSGDSPGEGAGDNKDKEKEYIKLKVVGQDGSEIHFKVKMNTQMGRLKKSYSDRQGIPLNSLRFLFDGRRIN +DDETPKQLEMDDSDCIEVYQEQTGGLN +>F4QFK2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:261658 +MSKSKIERDYIKKEEEEKEENDKVNKVGGINLQQDDNHDRHDDNDVVSTTLTTTINNNINNNNNNNNNNNNNNNNNNNVR +FVVPGTLVVGVNDEHNHKYNYGNVIRYVQLVDTNKEWNEEILGQYLKDAGFVRGSADTPSNKAKMTPIYTFKDDHVYKLE +IIGCGQLDLNRAITGIASPLFERFQSLLAPSYSIMTTLLTIAAYVMGIPKFGRGSLPNIVKHTLAEGIKIKEIPRGLQDL +AVKIQYTNNRYYGLVDQHRGVVWDKPKLTQYLQHNSIRQYKTTRYRPTQPIYGNIYKMCKMILCVVVGGVDNSFTEAKVG +EFIGLKDDGDDDYVGIAIVESALDIIGSMVLPFWKTKKIWSQVMRTSMVAVTLLAFQLGVPGYCHHPLINSCLKKEILDN +LEYSYYYYEFQDDVWKSLKECYFRVAEYLEKSLPQIYGNISYLFYSPPPPPIYSQPFLVNLKFEWDLKAVNIKVSTLETL +AQVKRMFYVEFGIDKSVEYTETQDMGFRFKYLNRPLYKADSMFVYGLGLRDGCLVKVVWESKWKTIQVQGYLKEALSMRV +QDTTVLEDIVREYYQNTLPPTEFRYLSIEYSGVKLELDGDIGSNRIKNNSFLLIVPDIIHIHIVPSWKTEEKEEEKEVYT +LHKHTTILSQLIGKFLDKHKLQPKQINFTNASTGALIDPNKPATHQSLEMDSIINATLVNSRLELFYEKQHADDTVSFIF +DINTTFGSMMLRFCQQVGIKDKDSVDFFYNDKRLDPKETPKHLNIGPHSNIKVVDQYTTNRHSSKHWY +>A0A2K5MG21|unreviewed|Small ubiquitin-related modifier|taxID:9531 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A4Y7JAY9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3469 +MGFGLRNHTSLPTNMSGVVIPEDDQKRIAEKSKRSIHITVMFNGDNSDIVCFRMKRDSPLSKLIDAYGEITGRYNHHTVN +FLYDGIRIRPESTPHQLGIEDGDEIDVFLVQ +>A0A5B6U8Y2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:47621 +MKLNQENGGPLLPLLRSLVVADGAGLRNSGRVTATPPADSTKDDLEPLFDYRRVQPLNIVCLDDDCLDTSPVPSPKRRKF +ANPDVAEVDLDKDVEVIKVVNVEEEDWLAPPPVVSTKAYSKIGEDSTIKELRRRKQELLSFAQSAKSMLQEEEESAKQEP +SGSSKLSLDAVAEQPKNPAPERAKIVISIQNKDEIKQFRIYMDDKFEKLFSLYANKAKLDLQSLVFSFDGDKINLAATPA +SLGMEDDDIIETFCLNLDMLTMK +>A0A9D3NQ85|unreviewed|Small ubiquitin-related modifier|taxID:337641 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGCYMEHFSPCVLAHVDLLTKNQETLEPC +>A0A3G6ZHT7|unreviewed|Small ubiquitin-related modifier|taxID:1234273 +MSDTETKPSSEGAEKKDGEHIKLKVIGQDNSEIHFKVKMTTHLKKLKESYSQRQGVPMNSLRSLFEGQRIADNQTPKELG +MEDEDVIEVYQEQTGGYWND +>A2YMX1|unreviewed|Ubiquitin-like domain-containing protein|taxID:39946 +MFGRSGITAAVKVEEEDDGKTPAAKRAGEYVTLKVQDTDGRAVYRTMRWTEQLQGLMDFYYDRAHGQVQRGTGRFLYDGR +RLSGWQTPAELDMEDGDEVDFFEELIGGAA +>A0A6I9NEH0|unreviewed|NFATC2-interacting protein|taxID:8208 +MAAEDSSATKSSSSLTVRLQSKDRDSSQEFSLHRDAPLGSIFSQYMSKMSAPAKSKVRFHFDGCKVTDRQTPAQLDMEDG +DIIEVWT +>A0A3B3UD77|unreviewed|Small ubiquitin-related modifier|taxID:48699 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGLI +>A0AAD5HS72|unreviewed|Ubiquitin-like domain-containing protein|taxID:2898545 +MEDKGVTSPPIVKKKLPFKPTALRRFAAPKPTPTQPEEKEEEVKESDDDGLSLFRRSKEMAPIVAADRERRLKRHQKHHQ +MDVERRSREAAHKRPRDESEEVVNQDEPVVSDEIESEVAASQSSPARPRSSQVSEQLPATQETTDRASELVTPPPSKRSR +LSSSSSSKKPIPALDLDEDDDEPFRDASPTPFQRKPSTPSRSPKMAQPPPAPTNVISIDSDSDSDDVSLKPTSVPASRRS +TSIVELVDRTSSRQSPKEPSPPPEDDEFAEYVRKAKERRDRDQALLQTGLDGKPKKEFVDILITSQVPGTRPLKLKYLFD +KPFRLTRETWSSYQNKSGVSIPVDDVILTWRKKKIYNTSTLLSLGIRPQGDGRVIAEGQGSEGFENNRSLVHVEAWTPEL +FQEMERNEELRRRREAGDISEEDEDQEEEPADDIKLKVMLKSRDLEDLGLTIRPETTVETLITCFRAQRKVDPNKQVALW +WDGDRLEEHVTMEEAEIEDMDTLEVYIQ +>A0A9P7VJ91|unreviewed|Ubiquitin-like domain-containing protein|taxID:1450536 +MSDEEVPGGPSQAEIKGENDPNAPINVKVVTSSGEEVFFKIKRSTKLSKLQGAYASKVGKDVATIRFLYDGNRIQEDDTP +ESLEMEDNDTIDVMVERTFVAFPFLFLMLMLGVVTTRGWRLCAAVTNPLLVAIFCFANQYDIQSCTTYRQLHSPFLVSSP +YMWFF +>A0A4W2E1V1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:30522 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>A0A8C6EYD7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9994 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKKHTPLSKLMKAYCERFYCQTHTIST +>A0A8C2DQ37|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:7962 +MDSGSRLHSELYWQKPISEGVRTENAHINLKVVGQEGSVIQFKIKRHTPLNKLMKAYWYTINEMPNEHTIINLCFHRK +>A0A4Q2DUN2|unreviewed|Ubiquitin-like domain-containing protein|taxID:2316362 +MSQEPEEDVKPKLNLNIAYEGQHVTVKVKANMKFAKIFEVVEKRFQKEPGTFKFVFEGQRVGKEDTPGTLGMEDGDQVDA +FLMQVGGG +>A0A0P0VC54|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:39947 +DGNEVFFRIKRSTQLKKLMNAYCDRQSVDMNAIAFLFDGRRLRGEQTPDEVRSLSSLHTQFSICGA +>A0A1G4ARM5|unreviewed|Ubiquitin-like domain-containing protein|taxID:1209926 +MADAAKPKRRLPFKPTALRQKSDPKPTPQKNDNEGDDEDDDDGLSLFKRSAEFFPVALAEQERRMKRKQAERERSSQARS +PQGETKLALRASEEPDKEDAEEDASRELGTPPSKRSRTSDESPQSRTKLSPYKRRDGTETPSKRLTRAAASRTPRKQEVI +PHKSVIAIEDSDEDADDVDDVASDDIYEASPVRKTQRRRQTSEPEVAPLVIDSDDPFTEGTNGDGKSPVAGVAEEGEEDD +EFEEYVRRAMERKKALEQEANQLVNVFVTSDIPGTKDRQFRYTLVKPLKMIRTTWIDVQQDRVAIPRAELEGVFLTWRGH +ELYDTTTLHSLDLAITFRKNGGGGGDGGGDSSEGFKDDDWTNVHLQMWTRELWEEHERQEARRRRHDLGDYSDDEGVGHD +DGAEAIEPETEKKIKVLLKTKTDEPLKTSVRPSTTIGTLMELFRKMRGLAADAPITLMFDGDELEEDMTVEEADIGDMET +IEVYIR +>A0A9P7WY42|unreviewed|Ubiquitin-like domain-containing protein|taxID:2600232 +MSDNEQGPAEPKPELEANAPISVKVVSSSGDEVFFKIKRNTKLTKLQGAYANKVGKDIASIRFLYDGARIQEDDTPASLE +MTEGDAIDVMVEQVGGAPSL +>A0A507EVI9|unreviewed|Ubiquitin-like domain-containing protein|taxID:117820 +MTDANDAQDERKPETVQHINLKVLGQDQSEIAFKIKRTTPLQRLMDAYVAKTGQDKSSVRFLYDGQRINGHETPDELDME +DNDMIQVSVQQLGGSAA +>A0A0K3CL61|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:5286 +MSSSSELEVVSKPRSPPKPRRSARERRVPRSIDEVAASAAPLARVTGASRRTGRASESSGLEYMGADTDGDLDMSGLDEE +DLGKGGRGGVVQKAPGAATMTAEVSTKKAAPAPAAKSTVVTLPSSSSAPDLSSTRTSPPPSTSARPASFSTSLQNDRSSA +APRASTSAEPIASTSTSRPLPPSRKAPRPAPAPKKAHYSSDEADDFFVRAKPAKGKVPAKGRVPGAAAGGAVGRAPAAAA +AKGRGGSATSRPSSPAKRKAVAISDSSDSDTSASSPRRGRAVSDSDSDGGDGMAGPSKSLKLPGWARSGRAGMSGADLAR +LKKGVGKNRKRKRLDDSDSDDGGLKAVEAIGTSKEAARMSSSESSDEDADTDDSLEIALGGGSKGKRKEKEPIKVAPAKR +KSLSPPLPSPKRLAKFTDRLPDAGLKPPSLGSLRTSPRKHLYAQPPSSPRNLFDRDQTPSISSAASENEEEVETGEMLDP +ALAAIRSFVGTSARLGASSGTTPSPQKNGSAAPIAAAKVTIKLKMVFDPTRVVPEMAKKVYEREETFELGLNEPFSALFY +ALSVRRTIPRSDLILTYLRHPSSATSTSRQTQVFEFGTPASLGLHGNADVDMRGYTQDIWEKCKKADAAKRASGGDDDLE +LEAAAAEAAARKAKSPSMADHGKGGRDSDDEGEAGEAFPLTIRGSATQSLSLAVKPSTTIAQLIKAYCRHFRITDAARQA +KMSVEFDHEQLEPTLTVQQAKEEYDLEGEETFDLKEAS +>A0A058ZZV2|unreviewed|Small ubiquitin-related modifier|taxID:71139 +MELALLWSSTLEHDFYSKEWNEVFFMIKMSTQLKKLMNVYRDRQSVEMNSIAFLFDGRSPQGDQTPDELKMEDGDEIDAM +LHQTSGARTLT +>A0A6A6MXH8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3981 +MDDSMEELEPLFDYRRVQPLNIVCLDDDGSDGSPVPCPKRSKIIQNPKSVVEEVDNDDLEVVRVNCEDKDEEDWLPPPPK +ACCDFRNQLVEDSTIKELRLKKQELESLAKSGVDVLRAVEESLKRELSSSLKAALNAVAEQPLKPPCGRAKIVISVQDKD +GLKQFRMYKDDKFERLFNMYMDKAKLNNIQSIVFSFDGDKVSPTATPDSLGMEDEDIIEVHAVQIRSASRFFVDYSAKSN +LMLPCGS +>M1B397|unreviewed|Ubiquitin-like domain-containing protein|taxID:4113 +MSGVAGGEEDKKPAGDQSGHINLKVKSQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPD +>A0A2B7WXH3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2060905 +MRSFFKKPDWAKTDSNPGQSAEFYRRSEQVYTDIISREPERDQRSEDDEKNEGASHNLQDGKLQELQPSLESNGSKRRRM +SREKSAPSTTCISPGSERWGKGEEDQAYIKETICSMQRMQQAPAAAMSHTQVKNLPAKVNNELHPPTAVAVELDSDSSKG +SSRPKSQSVQALQTHSKQPPKHELDDGEDDGDDLYAEEEYAELARKARARARLQRAASAGNAGPDPPAAGARTTQSPNLN +HTTKSTSNTPDRQNRPIEPIVRILITSDLPNTNPLIVQRRLNQDLRDVRRAWCSRQGFDDEMTASIFLTWKCRRLFDVTT +CKSLGVQEDKEKGLLQPLPIRDYYNDNDDDGSGQDGGSLEVHMEAVTEKLFEEKRRQAAKASHGEFGSSEDEDDDGDDDE +GGDGDKTAREAQQKQDVLLIILKSPGIEDLKIRVRHKTHISSIIRSFRERRNIPTHRTVQLLFDGDQLHPDSIVADNDMA +DLDAIDVRIK +>A0A9P8QDG8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:599730 +MSDPRKSNLEVQSDTGAVSSGVTHPPPSGPGPASTVLQNKILLQAQASNLEDSMSKDTSIKTNISEINETNKETLADNFI +NNDSQLISDTRRPLVIDTGTPSYNTENNSPTDTTNLETRSLLVGGTSTEIAPLNNENQPIKPIENTTRSTAAAAATTATD +TKTTVNKYQSITDDFFSLYTPTFGLPEPKKKKKKKVKKAKRESSIESTGSVKDESVVSVEDKSGTTLEPAAESTVEAVPE +VETVPQIEQVEPEVELVELGEEHELEPENQTANDMGLVNLDSGEEDEALILDEEEPMQSPLLAKKNAEELDSVNVVQEFT +DNKNNNKRKATTPVATDTPKVVKAVKIPSFTDYKRFTTSTSSSNNNYNSNDDDAYLEDDLLRKLKTHSAMPKFFRQSTAG +SATSEDSTSASATTASATETPDRIYSMKIKSNLPGSENQEVQVRSKGSKQFQSIMKKTLKYLITQRNLQGLQLLNHTMDR +IVLLWKQTHEISPYMKPDNLNIPANPDGSDTVIELDLYTKEQTSYLEEAKREQLRLEKEQKKKDEAMDQFLTQLQKQKEE +EERLALQGTQEDEEALGLLNEDDLKILSEVKSKEHSVEQPMTQNLEVNNNAAENEEDDYFKIFLKSADNEKLTVQVNFHT +RLSKLAAYFLEKKGLPADSKIRFVFDDEPLDLDSAVGDTELEEDFSIDVYVDK +>A0A4U7B7J3|unreviewed|Ubiquitin-like domain-containing protein|taxID:40998 +MATDTNPVPLAPKRSLFAKRPTWASSTTSTSPNPAPAATPEEIFNSPSNALPQLLKEKEERRRRKVEKTQAQARKEREAR +CKSDEARKESEEGWAKKRRISDKDYERFGLVSPAKKALQGEEKSEEGAHEDVEEETRGRSRKPGWEQEDDVSPGHEDPEH +QERTKPMRKSPRTKPRPNNIISLSDDDDEDENDNDELYTLSPRPASKPAPNSPPPDSEEEFPELAALARERRRKRELEAA +SGTPGSATSAAASKEPDFDPVIKVLVTSPLANTKPLLVHRKLSQRFMEIRQVWCQRQGFDEEMSQGVFLVYKMRKIYDVT +TCKSLGIRVDSEGAVLPERSREGFADGEDEAGRVHVVAVTEEAFEEMKRVREEKRRGATGSEDAEEGKVEESEEEVKKIR +VVLKAKGFKDYRLKVKPTTTIHKIASAFKREYKLADEQEVILKQDGEALDRDEEVQNTEIEDMDCIEVHLK +>A0A2K6JZS5|unreviewed|Ubiquitin-like domain-containing protein|taxID:61621 +MTTPLKKLKESYCQRQGVPVNSLRFLFEGQRIADNHTPEELGMEEEDVIEVYQEQTGGHSTV +>F2PHN8|unreviewed|Ubiquitin-like domain-containing protein|taxID:559882 +MASFFKKPTWAQASTPTKPQDFFRRSNQVYSDFVATTQDEDETDDEAVAAKETPCAPSEPKRRRISNEDDGEATSALQSR +IKSPPQETASRGDTVKRDTPPRLEEAETSKTSPRSPRSARSSPRKTGSQRNSPRKSQLVGASPPGTIIRLNSESPPPPAS +RVPPKSVIQIDSDLDNDGDNDEESDEECAALIRRARERARNNLLREENKLASPNDKDNDTRKTTGTPSTSPKAASSSSPK +KKDTVVNILITSNIQNAKSLLVRRLLSQNLGEVRKAWCNHQKYDEETSDSIILTWKGRRLFDVTTCKSLGINDTDTNDNS +MFDSSPFDMEEGNAGVHMEAMTEEMLEERRRAATTIQQDNNEEKSEEEQPKAQEPADTDLLRITLKNPDLDDLRIKVRPS +TQIGNILKKFRQVKEIPEHKSVSLYFDGEKLDPDTLIEDNAIDDMDCIDVIMK +>A0A7S4R1Z5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:311494 +MGCRLTPLLLLVAVARAQNLGLAYSNTPADALSLVQIEAPPSWFTKLGSLIKKAGPAGKEAAGARDTALDAGSRPAAAQG +QTSSGSQQAERSAAEERAVQKATTERQLEAQRAEAERRQAAVKREEEEEARRRAAMKQKEEEQVNQRAAMQQQEEEEEAS +SKAEDTKRLELAKLMGEPEVGGGAGPEAARPKAEARPHEQAAPPAAVEPQAAVDPEARRLQELHDKVLREMREKIMSEAD +AAVKRQMREKHAARLEELKRQKAEEGERMKRQQAAREEQQKLAEEEARQKKLDMERAKAERLQAWKIKQQMKLEAEREAV +RKHKAAADRLVDQQRRKTQIGKRREEEARRHPASEEVTEFPEGDANFINVRLQDGLNREITLKVARAVRLKAMMMTACQR +FGLDRDYASFSFNDRPIRFTDTPESVGLQNGDIISALEVADGEFTE +>A0A8H7HZP6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:456999 +MSARPRPRPRPKPKVTSEASTSGTLFESSKAKSPAPDDDDIFLRHDPNRLLYNNKKSREKSPLRDVKYFDNDSDESPDSK +RRKKELAPKRAKPLPSWTFQPRDPTVVDIQSDDDSSELEILEDDAFKDVPSAPLPKPKLREKSITPPPQHLRYQVGNQVH +ELLHNLYDVDDDRELSPEMESQDAIQLLPELAAIQRNARASSAAPEIEDTRFVNLHIKWIPHPMEPQPWEKNLPSWEFNV +PLNKPFGEIRRMLTGLPMAVQPILRSKNRRLFDGGTPASLIVGSKLEIQAMTKLTNEYFEDHHQLPLSAHGSDIAEHDDD +DGSQEGSSAAVEKIGLRLRTGPKDTRPTTVRVLPDTTIQMVIEAFLNKTGRVGMQGVTLQIDGDDLEMDSTVADADLEDG +DLVEVAGIE +>A0AAE1T6U2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2727404 +MAPENGSKTSQPTANHQAANAVKLAVKCNKDGKETFFVAKRNMKIRRLLTYFCRYASLDYRSTRFVLDRRPFSHEKTPNQ +LGLQDGDQIDALIDGNGA +>A0A7N9DDB9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9541 +GDSGARHGRRKAQGELGAGPSPRRAVGSGRGPGSGQSSPLAPSAFPGPPQGRPQLRPRRSAPFSSLPLFLPPAPEEAPPL +SPAPGGLRVRAGRELGGQIADARGPTSPERGFLAQPTGAREEGVRARGVSTLRRPRVGCCSLRGGGESPGLGLHLSGVET +AGIWGLLPGAAAAGRGFGANQWAADEQEPGCPLAAVLGLGVGGFPWSISHFNGLRDLRGEGQRLFPGCQRTPNPRRPCGF +MKLEAQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>A0A8J4IHF8|unreviewed|Small ubiquitin-related modifier|taxID:156760 +PQQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGVY +>A0A072PBI3|unreviewed|AN1-type domain-containing protein|taxID:1182545 +MRSRSDSATSNNSNKELSADNMAIQVTIGGGKTIKLNVRPVHTVSNVLEFLSASTNLPADVQLMLDGKPLDPSSTVGELK +LEESSTLQLSSPTRSTTPEEQTAPSSQEQQTSSQQQQSAVIKPSISTPTPSSSGTATPTKRKSNKPRCSKEGCRAPAQPI +VGDCGFCQKRFCGKHRMLESHNCEGLEDARRADKDRNTAKLEGERTVMLRGL +>A0A182PUB6|unreviewed|Small ubiquitin-related modifier|taxID:199890 +MADEKKGSESEHINLKVLGQDNAVVQFKIKRHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTTLDMEEGDTIE +VYQQQTGGSF +>A0AAD6MD78|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:444605 +MGLPTHTAQNGNGSLDTGNARLKELGYKQELKRDLSVFSNFAFSFSIISVLTGITTLYNTGLNFGGPVSLQYGWFIAGGF +TMIVGLSMAEICSSYPTSGGLYYWSAKLAGPNWAPFASWITGWFNIVGQWAVTTSVDFSLAQLIQVIILLSTGGKNGGGY +EASKYVVIAIHGGILLLHAALNSLPISVLSFFGQLAAVWNLVGVLVLTILIPLVATERASAKFVFTHFNTDNGDGINSKA +YIFVLGLLMSQYTLTGYDASAHMTEETKNADKNGPKGIISAIGISVIFGWFYILGITFAVTNISSLLDEDNDAGGYAIAE +IFYKAFKGRYGNGVGGIICLGVVAVAIFFCGMSSVTSNSRMVYAFSRDGAMPLSSLWHKVNNQEVPINAVWLSAVISFCM +ALTYLGSEVAFQAMVSIATIGLYIAYALPIFFRVTLARKSFIPGPFNLGRYGVLADSVEDLDSLFDYRRVQPITILDEDD +DEEYDKPPVPSPKKRKISKHNVEIVGGDREASQVTNDDEDWLLPPPKDSSESPKQIDEDSTIKELRLRKQELKALTNKEC +LFQYLESPNRQSDSVQADLESGAEQPSKPHHERAKIVVSIQDKDEVKQFRVYKCMKPGRFKGKYATRAAMNLKRKPVMNS +SLTVQDEKFERLFKRYADKVKLGIESLVFMFDGDKINLTATPDSLGMDDEDIIEARYLLAAQLFRILAIKCFKGSVCLRW +LTVL +>A0A2J8A7P0|unreviewed|Ubiquitin-like domain-containing protein|taxID:47790 +MVRVRVWPGSGGLELFRLQLQGLGGAAGQALHTSQLMELFSSTHPRSINGLSEPGVTTAALVAAGTLAAAVGAGAAGAGI +GAAAAAPKIEAAAGGVGPGQTRRAAGVLACPTSAPLHGWRRVGEAEAEGGGGGKARRLTREGGRDGQPADAAGAVGAPNQ +PGARSLNIIVRELDGGEMSFKVWPSTKMGTVIDAYSVSKAVDPDQVRLVFGGGRIPDDCCPADMGLEDGDVIYAMREQIG +N +>A0A8H4YVW9|unreviewed|Ubiquitin-like domain-containing protein|taxID:48485 +MSNENENGTPGEQAPANSEHLNIKVTDNNNEVFFKIKRTTKLEKLMGAFCERQGKATSSVRFLFDGTRVQPTDTPDALEM +QDGDTLEVHQEQVGGSAQ +>A0A0D9YHE2|unreviewed|Ubiquitin-like domain-containing protein|taxID:40148 +MSSTPAAADTAETDQADLKPVKAEPGTGPGLITITVTSQTFADVYFAIKPRVKLRRVMDLYCGKHSLDPKTVKFIDDDGR +FVRSEQTPEEVGLQDGSTISLAIDQQGGACICEN +>A0A6P8U488|unreviewed|NFATC2-interacting protein|taxID:8218 +MAEMVSDEEQEAVNPQPKRRRILDPSAIISVPVYTNQVSNGLQLKPTAASFTQKQISDDGADDGADDSLWFQFSPAISRT +TAVSYIDSEEDETEVLLKNTQPATFSSPSPPGSPEVLQSRHAKNMINKIDIKLRAANTLESPECRRRHFIEEDDDIICIN +PNPGPQNSPYSESLREIPLKIRCMTHVHKIPVLSSTPLSDVLTRLSVILDAPPPRLMLLRKEEELPANSTVGELGLGIAD +IIECVVMAAEDSSATESSSSLTVRLQSKDRDSSQEFSLHRDAPLGSIFSQYMSKMSAPAKRKVRFHFDGCKVTDRQTPAH +LDMEDGDIIEVWT +>A0A8S9L647|unreviewed|Ubiquitin-like domain-containing protein|taxID:69181 +MVSSSTTISASCASKGSPSLSPQKKITLKVKAQQDGGEDVYKIGYGAHLKKLMDAYCTKRNLERTTVRFIFRYKELKPRQ +TPAQLMMEEGDIIDIVTDQGGG +>A0A8H7Q0J6|unreviewed|Ubiquitin-like domain-containing protein|taxID:44442 +MSDSEKGIEKKEGGSEHINLKVVGNDHNEVFFKIKRSTQLKKLMDAYCERQGKATSSVRFLYDGIRIQPTNTPNELDMED +GDSIDVMVEQIGGC +>A0A2J6PDR9|unreviewed|Ubiquitin-like domain-containing protein|taxID:2082293 +MAQSDRSASSGAEPQPKPEDALKPKQLSIKIKNQQEAEIFFRIKTSTKFGKVFENYCEREEVARDSVRFLFDNIRIHDHD +TAAGLEIEDGDEIQCVLEQLGGDGTPGGEGEPKPEDQAPTQLNVKVVDQEGNDLFFKIKKNTALKKVMDAYCTRQGKTRG +LVRFLFEGHRIQDNDTPDTLELEDGDMIQVFLEQQGGDGGEGGEADPVQKHVTIRVKDDAGQETTFKLKKTTPFKKLMDA +YAQQQGKAPDSLRFYTSEGGRVQAVDTPDSLELEDGDLIDVHIEQQGGADDF +>A0A7R9ILI3|unreviewed|Small ubiquitin-related modifier|taxID:61484 +MYRCVDSMMQGFSYLEEHSQVLYYGDSNEIHFRVKMTTQMGKLKKSYSERVGVPVTSLRFLFDGRRINDEETPKQLEMEN +DDVIEVYQEQTGGHF +>A0A260ZS93|unreviewed|Ubiquitin-like domain-containing protein|taxID:1503980 +MSDSDDNLDDDYLERRRVALQKKRQPVRVYESDSDDDFPSKKKLVAKRQREIEELNDSDDDSFVEKPDRRGEHQKHRIED +VEGEYRRKIFRTDTVIHVQNEKNDALGKAMRIAEKMCHSKSTESPERIINQPEDPAELSIEAASFPVTVTIVDCVSRLSS +TGLINKHDLPLTSTFSGIRNGLAEKWKCRVDEVTLTYNGRIIGDSETLRDIGMSPLQMPQPKVEAFKEEKKAPEVFTVEG +TPDHITIKAQLKDRKKPIHIEVLKETTVEEMMQKVINVLSEGGEKFIPTIETMKVMFDDEYCNKTQTCEELGLEEADCID +IYC +>A0A0H5CJ92|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:983966 +MNEAVEPTVAENGSSEAIDLTQTPPGVAGSVIAEAVDAAMTAADSATGAVSTNVTCSNIGAITPGGESGVQTQLERQDTL +ALTQPDEVPSQMGALDSNVKTESTSMGAVDSNVSAKTTSVETYAIDIDDDDFFNLSVRPSFVEKPKKRKKKKKRQREDVT +SATPDADDLRKRTSLSPSPVIASSKKSSITTDDKGDEDVLIVEEIQTAKPAKKPKVVLDPNFDENAIRQRIKEQTALLYA +QSNDIYGDILDDNDEDDISRRLRLTEKKASELLSQREPGSAIERSISVEPVEKRKYNVTVESFIPGSEHYQLTLAVKGHK +NCAALISKSVTSFAAFNAVPESLIYLYDPVNVTLMKDKIELKEHMKLDSLKLPVPESGITDVHLSLYTKLQARAILENEQ +RERDKRLRQLEREEELDRFAHAKINDDAYETYADDDEFRDIDKEIDMESATNEGMVHLEPGPAENEQDSAYFKIVLKCDE +KTRMEVKVKPDTELSRIAEHYLAKSGLPSTTKIRLVFDDEDLNLNETVGDTELEEGFTVDVYH +>A0A663EAF1|unreviewed|Small ubiquitin-related modifier|taxID:223781 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPISETDTPAQLEMEDE +DTIDVFQQQTGGAC +>A0A6P6SGK9|unreviewed|Small ubiquitin-related modifier|taxID:13443 +MSQAAEEDKKPSGDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDLNSIAFLFDGRRLRGEQTPEELEME +DGDEIDAMLHQTGG +>V4LGS3|unreviewed|Ubiquitin-like domain-containing protein|taxID:72664 +MKRRTQLKKLMDAVCERVCVDFNSMAFLFHGRRLLGGQTPDELDMEDGDEIDARLDQSGGGITNGLYLSCF +>A0A0G2F7E6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1214573 +MGTPIKAFKKKKTFAFLKSASKPTPSLESTGNQLEQEAGGDDDELDLFRRSRDFFPMVVQEQEHRQATPEERSEEQDRFS +QASTQSPSPASSKRRKLSPPTHMDDFRDTEEDLYGPPTPPRRVTKSRSASPRKAHIKRPTPSPAKAKGKERMPAVHSDVL +LTPTRSSSNQPYANEVITLDDEDDGAVEELHAGTPALATTASTTASKDVSRILREEETPSPGSITIDDSDDDVFENTNDP +PDKDDPFAHFIQRAREREAAAKAEAAAAAAASRSEMQPSTPEGAPRKGREPVIEVKVFVQSRIAKFPDVGPFGAKRGMSQ +NLGVIRRTFLLWLRKLGHPVSEDDEANIFFTWKRRKIYDVSTGVSLGWNPSVAEDSSSSSTPGFTKGGVLLEAWTQEDFD +EWLAEEERQRMMKRGDLVEDVSDDEPVEEQVDNTKIRISIKEKDQEPFKVAVYVDMQIRLLAPAIRKMRKIPNDREIKLR +YEGEWLDEDTTVKEADIEDLCTVEMYLR +>A0A6P3HUR1|unreviewed|Small ubiquitin-related modifier|taxID:43346 +MSDQEAKPSTEDLGDKKEEEYIKLKVIRQDSSESHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGSFNGLDILFIFFSFPLILFYF +>A0A3F2RN90|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:325452 +MPEKAKSPAKPVNLLDDEDEDDDELYTESEREAERLRKARLEREIRQTLAQDKVLNQTRAVFDRVSSAKNQVILLDSSDE +EDSVESADGGDVATVDPDPVPEVVTAPTEPVVNKGPRITLHIRSNGGAVDEISIYMNETFDALYTSFCELHGLPQSAVKM +SLDGEPLSLTDTPANNDLESGDLIDAKVDFSKQNQAKKKTYLRLRLVVFGKRSEVFKIDASETIEKLHTSYCKRHGITNP +DDVVMSVQGQELSLNERIDYYGLIDSDEIAVKINNFVDPQAIELQLRYTEGDPEAHRVLPVS +>A0AAD3S7I7|unreviewed|Small ubiquitin-related modifier|taxID:150966 +MSGVTNAQDEDKKPSDQSAHINLKVKGQDGNEVFFRIKKTTQLKKLMNAYCDRQSVEFSSIAFLFDGRRLRAEQTPEELE +MEDGDEIDAMLHQTGGTMI +>A0A4D9F2P0|unreviewed|Small ubiquitin-related modifier|taxID:55544 +MSDQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0AA38W9D3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:347529 +MASSVKQKHPTEEDKDSIINVNQQHETGDSFITLKQPHQQTGNSSTITVKQENQTGDSIITLKHQHQTGGDSIITVKHEH +QTGDSFITVKKKQQHPTGEEEDSIINVEVVNPLNRSIVFRVKRNKPLQVILTKWKEMEGITDYQKVYFIYNEHRISDDDI +YKKNKTVKDIGLKDGDCITAQLSFIGD +>A0A1Q9EV64|unreviewed|Ubiquitin-like protein pmt3/smt3|taxID:2951 +MASIPTIFATEWADARLAIRLTMLNTSWQRVMVEWLEVQTSVDLRNACDAELTSVSRLCPKLESLDISDSEALTSSAVVD +ALRRCPNLKTLIAWGSNPAQTLRGWRAIQEAKPDLAVVGRQARLVIRVRAPNLGWDREVRFDVREGLPLGKLMETWCSRF +GISSSQVRFLSDGERISPSDTCASLGLKDGDELDAVLEQMNIGQWQALDVPEASMTQLDRLLHGKLEPHQVAKETVLSIA +RSVLAPAASPGLQTMNSVQGEVALPWKSCKVLDRDQCKKLAEWTESSFERGQDVHDFQLRLTAAQLDQLTCDNTSRTLTA +CAESVLNGQEVAPPYFILRRHAASDRQRLRIPFHRDYSLAVVNVSLNSEYTGGKLMFVDGARLICPERKPGCATAHNQTA +IHGVSSITAGVRYNLLAAFDSAE +>A0A6J3LFU6|unreviewed|Small ubiquitin-related modifier|taxID:207650 +MSDEKKETKAESEHINLKVLGQDSAVVQFKIKKHTPLRKLMNAYCDRVGLAIAAVRFRFDGEPINELDTPTTLEMEEGDT +IEVYQQQTGGLC +>Q2EF74|reviewed|Small ubiquitin-related modifier 1|taxID:43179 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSNV +>A0A8J2N2E6|unreviewed|Ubiquitin-like domain-containing protein|taxID:119953 +MSDNGSPNVQQKPEDGGQSEHLNIKVTDNNNEVFFKIKRTTALGKLMNAFCDRQGKNISSVRFLFDGQRVTAADNPDTLD +MQDGDTLEVHQEQIGGC +>A0A9P1HH78|unreviewed|Small ubiquitin-related modifier|taxID:2878363 +MSEVPNTTSDGGENAGAQEYIKLKVVGQDSNEVHFRVKYGTSMGKLKKSYADRTGVNVSSLRFLFDGRRINDTDTPKTLE +MEEDDVIEVYQEQLGGSF +>G3B359|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:590646 +MESTRAADSPDPTLMSSGSSLVSSGNLVSSDPLVSSDAPSTSLRQDDQSASKHHIDEDDDFFMLKPRKKSRRRHRHSDMK +AKALEPTGTEPTGTEPTGTEPTGTETAGTETGIEITETQTQPTQTTQTGAGAVTPSPIELSSDSPVYHDADEDFTATVAV +PASHRRTRQSTRSSPPPKPNPSPPSVALRHSANPDDFARIMESVRQLRTESQLTYEFSPHDEENRPYLLNVIPKVHTTTP +NSFATKGNKSFKLILQSILLHYKRIGQFPKNARVVDYTLFWIHGRRELKHFFRPSTLRIYPPPEDSLVYVNGIGYTALDC +LLISRSMAANALDTFDELKTKYETLIGLNETYELGEADGNDSVDIISVGDTDDEDERQQGVGGSSFTIFLKGKDNKRMPV +SVTAATPTINLLKYYFEKSGVSEVTDLESGILVFDDEPMDLSDVVGHTELEEDFEVEVHFKS +>A0A2K5IF24|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:336983 +MAHEKPKEGVKTENNDHINLKVAGQDASVVQFKIKRRTPLSKLMKAYWQPINETDTPAQLEMADDDTIDVFQQQAGVSPP +TSHPTGLVLSCGQD +>A0A428UAB3|unreviewed|Ubiquitin-like domain-containing protein|taxID:2604345 +MSGENENGTPGGERAEAPANTEHLNIKVTDNNNEVFFKIKRTTKLEKLMGAFCERQGKALSSVRFLFDGTRVQPTDTPDA +LEMQDGDTLEVHQEQVGGCSL +>A0A2K6MT02|unreviewed|NFATC2-interacting protein|taxID:61621 +MAEPVGKRGRLSRGSGTGRGGRSGWGGRGRRPRAQRSPSRSTLDVVSVDLVSDSDEEIVEVTSARCAADEVEVAPSESPG +PVASRDDSDSDSEGADARPAGPPREPVRRRRRLVLDPGEAPLVPVYSGKVKSSLCLIPDDLSLLKLYPPGDEEEVELADS +SGLYQEGSPSPGSPWKTKLRTKDKEEKKKTEFLDLDNSPLSPPSTRTKSRKHTRALKKLSEVNKRLQDLRSCLSPKLPQG +QEQQGQEDEVVLVEGPTLPETPRLFPLKIRCRADLVRLPLRMSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPR +TLKLGVADIIDCVVLASSPEATETSQQLQLRVQGKEKHQTLEVSLSRDSPLKTLMSRYEEAMGLSGRKLSFFFDGTKLSG +RELPADLGMESGDLIEVWG +>W1QFL4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:871575 +MSHLASRAEDDFFAFSDEPVAPPKKKRKKKDKRPKSESSTVDVEVHEPEKGPKEFAKEESAKSESPSNKAQYDNLIEELG +LQTVEENVKKSVSVKMKKIKTTETNNDDQFLKELDKDIELTQPDGELDEILQKYSSSEHLVTLNGRQIPIKQALFALTVE +VALEDDEQIGFHLRVRSNAQFKTILREILKQLELHNRNLPSGWTDDIESLVFYVQDHDIILTQDLRVGSLLLSGAQLPVS +DAGDAFAITAVLTQEVMARKQRREASLEKLAQSQDQTEDLDEDELIVIILDPQKNNEKTSLSAEKGTTVKELLDIFLVRM +NYPDSLKIELRRDGLVLDKTIPVDLQLKNNDVVEVVYNLEDLESFEEQEITVISDEDVMEPEQSNYFSIKLKGKDQKEVR +AQVNPKTKIKTIAEFYLSKVGLDPNTRIRLVFDYEELDLSANVEHTELEDGYLVDVELL +>A0A2T4A126|unreviewed|Ubiquitin-like domain-containing protein|taxID:983964 +MGCCFSRSAGPNSPYPGGVPDASSRAINPPPLTLPEGIISSNPQAAALSHHHRRRRDPRPLDQHINRPLRRHRWTSTQRV +WTRRDLVKERAEFFDTRVVCRPEIWQTLHAALQVLWEANPEDSQDEDNALATAQTILTAAEISLPTGNLVNGAYDALGNL +YALPEWVVADPDNLADDRDPDAKGDGSTAGEETAGEDDDDADSEEAERRREEKGKGVLDEREMVTFRARLSETGRDIKVT +VAKTDSVRSVIKKITEQSTLPLDKKIRLAYMGKMLKENSSLEAQGWHAGHVINALVFNR +>A0A7L1NKJ7|unreviewed|Small ubiquitin-related modifier|taxID:113115 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A0B7FYZ1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1108050 +MADVTSTQDAKMMITITHSKGAAPDVKVAVKKVSQLRKVFAAAADRFRTTPDALIFKYNGTVLEGEHTPKMHEIPEGGII +TAYPAGEEEPSTQNVQDTQVTMDGFGDNAMEQDDTGPPSSSAKNDKITLVIRSQEGPSFNIKVVRGKPLKLAFEKAHEQF +RKAPKTFRFFYNGTRLKEDDTPKMHEMENNDEIDANIQQVGGASV +>A0A2U1MNS4|unreviewed|Ubiquitin-like domain-containing protein|taxID:35608 +MSSHTVKQEDLSGDSAENLYITIKVASQMNELDPYFRVRRDEPLKQLMIRWCARSGVGDYKTIRFLDPEGTRINEKKTAD +ELGIEDGDVIDAMMDQISG +>E1ZBV9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:554065 +MDDLWGYGGDEPEPDHFSDSSDDRRRARSDSEEADLLPQKKRLKLRQLGYGNGGRRGRRGARGGIGQGGEGDAEVLVLDS +DDDSDRQLLREAARGGAAGRSTASSLAAATAAAAAATAAAAAAGASRAPAWRQGSGGAAAALDPRSAALLQQAQAIQQRL +KAAQEEELSEDEDSEAPDPSPVVLRGAAAAGAAAAAARQRQQQAQQPRCSRRCDLDLTGDGSEEGSPGSGAAAGSEEGEG +SPGVAGGSPLPQAAAAADEGRISLKLRSAHAGEKVMRMRREDPFSKLFAAYRSWAAEAGHISSADAALRFLFDGDQLGPG +QTPASLELEGDECIDVYF +>A0A6A6DA79|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314779 +MSDGGSSNVQNSEEPQQSEHLNIKVTDNNNEVFFKIKRTAQLKELIDTFCDRQGKSPASVRFLFDGQRVQPTDNPDTLEM +QDGDTLEVHQEQIGGC +>Q5CUZ3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:353152 +MEERNIEENNEDDDLFGEDIAFSQESVNRRLGKVQKRNRLAKKVCINKESQQNETREKISSNDNNHIEEDSDYEEFRPAV +RKKISRKEDTVLTIEKTQKKVGTKNEQVSQVITIEDEEREKSVIKLNVKVYKRKESDIIVIKTLVVALYRNDLVKKLVTY +ISKNLNPKPEKYLEDIKVYFDGDCVNMEMEIKEIGIEDEEQLEVKVPFECNWIK +>A0A7L1I928|unreviewed|Small ubiquitin-related modifier|taxID:227226 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>W5MVX5|unreviewed|Small ubiquitin-related modifier|taxID:7918 +CSLQETKPSSQDSGDKKDGEYIKLKVIGQDNSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNQTPKEL +GMEDEDVIEVYQEQTGGLWNN +>A0AA39PLN4|unreviewed|Ubiquitin-like domain-containing protein|taxID:153914 +MSEEREDIKPKINITIKYAGDGEKQITVAVKRTTKFAKVFTAAEKKFEKDPGTLKFVLNGDRLRPEETPGDHDIEDDDII +YAFLEQQGGTRFIVFT +>D7MV06|unreviewed|Small ubiquitin-related modifier|taxID:81972 +MSATQEEDKKPDQGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMEDG +DEIDAMLHQTGGAANGLKLFCF +>A0A498JZR4|unreviewed|Small ubiquitin-related modifier|taxID:3750 +MSDPSGIITPDEAKEQKPTINLKVKINKDGSEVFFRIKPTTKLNKLIDALCTKRSLDRNSLVFIFDGDHINGKKTAAEHH +MEDGDEIDVFLLTDGGSLTFKSY +>A0A2K6ADW5|unreviewed|NFATC2-interacting protein|taxID:9568 +MAEPVGKRGRLSRGSGAGRGGRGGWGGRGRRPRAQRSPSRGTLDVVSVDLVSDSDEEIVEVTSARCAADEVEVAPSEPPG +PVASRDDSDSDSEGADARPAGPPREPVRRRRRLVLDPGEAPLVPVYSGKVKSSLCLIPDDLSLLKLYPPGEEEEVELADS +SGLYHEGSPSPGSPWKTKLRTKDKEEKKKTEILDLDNSPLSPPSPRTKSRKHTRALKKLSEVNKRLQDLRSCLSPKPPQG +QEQQGQEDEVVLVEGPTLPETPRLFPLKIRCRADLVRLPLRMSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPR +TLKLGVADIIDCVVLASSPEATETSRQLQLRVQGKEKHQTLEVSLSRDSPLKTLMSHYEEAMGLSGRKLSFFFDGTKLSG +RELPADLGMESGDLIEVWG +>R1BBV2|unreviewed|Ubiquitin-like domain-containing protein|taxID:2903 +EVEYLNIRTVTQHGSEIFFKLKITTPFQKLMHAYCSRQGVSLSAVRFIFDGTDINETQTPAQLDMEDGDVIHVEVRQ +>A0AAD9U7L0|unreviewed|Small ubiquitin-related modifier|taxID:168575 +MSGVTNQQEEDKKPNDQSGQAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEINSIAFLFDGRRLRAEQTPDE +VSFSHIIQSLTPPPTLLFLHQHTPTFGFEYKSH +>A0A1S3YXD3|unreviewed|Small ubiquitin-related modifier|taxID:4097 +MSGSGVTQQEEDKKPADQAAHINLKVKGQDGNEVFFRIKKSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRSEQTPDEL +EMEDGDEIDAMLHQTGGCLG +>A0A7J8B8A5|unreviewed|Small ubiquitin-related modifier|taxID:9407 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQVRCGRGRLRGLSMRQIRFRFDGQPINEADT +PAQLEMEDEDTIDVFQQQTGGSRETGCPAGRRL +>A0A0F7RXC2|unreviewed|Ubiquitin-like domain-containing protein|taxID:49012 +MSDAEVQQPKPEGAEQLNIKVKDADGNEVFFKVKRTTKLSKLKKAYAERMGKPENSVRFIFDGQRIGDNDTAETLNMEDQ +DEIDAMIEQLGGC +>A0A852J4Y7|unreviewed|Small ubiquitin-related modifier|taxID:240729 +EGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPISETDTPAQLEMEDEDTIDVFQ +QQTGGVC +>A0A3Q0FY09|unreviewed|Ubiquitin-like domain-containing protein|taxID:38654 +MVRPRAQPPRAQLHARHRPEVRRPETLELIWLFFRVALGARAVVTIFIPHSPTRPTPCWKVMLLEVELSNYSSNHDLSPR +QRGFNHSGKQNLPLRTWGIRKRENILNSKLLDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPK +ELGMEEEDVIEVYQEQTGGHSAV +>A0A396GDL5|unreviewed|Ubiquitin-like domain-containing protein|taxID:3880 +MPSIVISNETPSVITNDVEEIEPQPTNYINLHVKDTDDIKLYFRLKKTTQMRKLMDSIVISNETPSVITNDVEEIEPQPT +NYINLHVKDTDDIKLYFRLKKTTQMRKLMDSYCDRNALDFYLMVFLFNGRRIYPHQTPYELDLEDDDAIDAVLHQQWRRE +PINIKVKGQDGFQASFRIRKSAALKKLMDQYCYQYCLDVNGVGLLFNGYLVQPEQTPFELGIEDGDEMLAMLHLRTGHAR +CL +>A0A834VG83|unreviewed|Ubiquitin-like domain-containing protein|taxID:52283 +MSVWNCSYSILFYFILFLVMLSRSNGRFSIHRFHKRFVEDLVIDNQSILLYSKDFESEVFQKEFKLEENKKMADETDKSS +VSGPSAEYIKIKVIGQDTSELHFRVKKTTSFAKLKKSYSDRIGVPLPSLRFLFDGRRIDDQDTPQALEMEEDDVIEVFQE +QTGGSAIIDHSSTKFYHSCLTFDLVSTTKPSTTTLS +>A0A6J1XXQ4|unreviewed|Small ubiquitin-related modifier|taxID:32536 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSRDSRCR +>A0A5N7B424|unreviewed|Ubiquitin-like domain-containing protein|taxID:1226010 +MADLGMPAGDGPAPVEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCERQGKQISTVRFLFDGTRVRPEDTPDTLEMADG +DTLEVHQEQIGG +>U7PZU4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1391915 +MSETNTPNPADNKDGAAAGGNGEAAAPVEHLNIKVTDNNNEVFFKIKRTTKLEKLMTAFCDRQGKSLSSVRFLFDGQRVQ +PSDTPDTLEMQDSDTLEVHQEQLGGGN +>A0A3Q3F4G8|unreviewed|Small ubiquitin-related modifier|taxID:56723 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRISDNQTPKEL +GMEDEDVIEVYQEQTGGLWND +>A0A3Q0G591|unreviewed|Small ubiquitin-related modifier|taxID:38654 +MPGRGFAVYGGRAGEPAGQTRPGFCPKVAATVLRREGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQG +LSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTGGVY +>A0A0B4G8X8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1276136 +MSNEDDSNLQKRDELREHLNIKVTDDNEMVFKVKRSTKLEKLMNAFCDRQGQSPNSVRFLFEGSRVQPTETPDTLEMQDG +DTIEVHQEQIGGGEMLKSSHSQSTELSANNMREGRLQPSSSYAICKIGGRYFAFPDTVM +>A0A9W9CMS2|unreviewed|Ubiquitin-like domain-containing protein|taxID:798079 +MPDAQQDAPAPKKRSFFKRAAWQDAPKKDSDDIFSHADEFSDIVAEQSRRREEEERRAQSQRQRNKKRRKVSLENEEPMS +PGSTSGGVLKQNLDNDVPSRIRTPEPPGSVPDSLSARYDSLTRIASSKDSLDRKQSIVIDLDDIDDQETSTHNSNSLAPN +ATLAPASRNEHRERDMPILSSRRAPTDDHEIEEVLDPTLAALAARARKRAALKAQSAVGTHGEASKAPIAQLFISPEIPD +ANPLMVKVRIDSTIEKPRQAWCAKQGFPADMTRNVFFTWKGTRLYDSTTIKRLGMQVDKNGNVSVEGDPNIYDDVNVPKV +MVQAWTEALFQQRTKEDAAAKKLAAEVPPVVEEREPTPESVLQVTKIRLILKARGRDDFRLSVHPDTDFAHIAQAYKTRL +KIDDNQPLTLTFDGDRLSPLDTVADTEIEDMDAIEVLFK +>A0A341BTL8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1706337 +MADEKPKERIKMENNDCIDLKVAGQDGSRVQFNIKRHAPFSKLMRAYCERQGLSLEVEDEDAIDVFQQQTGGVY +>A0A7K7SRD9|unreviewed|Small ubiquitin-related modifier|taxID:239371 +VLRFCTREGMKTGNDHISLKVAGQDGSLVQFKIRRHTPLSKLMKVYCERQGLSMRQIRFQFDGQPIKEADTPAQLEMDNE +DTIDVFQEQTGGGR +>A0A6A4KDV7|unreviewed|Ubiquitin-like domain-containing protein|taxID:262921 +MAAGVPKKDKTHVTVKVQREKEFDIYVRVRLEAPLRLLKHAYCDRVGLDCDEVRFTYDGTKIRDLQTAGDLKMEDGDVID +AWSDQTGGGASA +>A0A553ID09|unreviewed|Ubiquitin-like domain-containing protein|taxID:2512241 +MSGENESGSPSAERNEAPAGGEHLNIKVTDNNNEVFFKIKRSTKLEKLMTAFCERQGKNVDSVRFLFEGQRVQKTDTPDS +LEMQDGDTLEVHQEQVGGQC +>A0A167SHT0|unreviewed|Ubiquitin-like domain-containing protein|taxID:1081102 +MSGNNTPNHADNGGDGSGAPAPAPVEHLNIKVTDNNNEVFFKIKRTTKLEKLMAAFCERQGKSMSSVRFLFDGQRVQLSD +TPESLEMQDSDTLEVHQEQLGGAW +>M3XMN1|unreviewed|Ubiquitin-like domain-containing protein|taxID:9669 +MSDQDSCSFSHLPPPRMGNSCIARRIIDKLEEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQ +RQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTI +>A0A553R0E2|unreviewed|NFATC2-interacting protein|taxID:623744 +MEKNEEKDHSPPRKYKPVVSIDLSGSEEETEPTEPRSKTFFVRHNEHVCFTREINRKLDAIGSLVYCSPEPQEPEIEYRS +SPSPGKDYDDDDDIIIISSDNKQNRRPSNAEDRGRVISLKFRCRTELYKIPLLTTAPLSKAVEQLALKLNVSSSHILLLK +KDMDLPVHSSIAELGLGIADIIDCVITENKREESSTSDVITVRLQGKEKTSLLEYSIKNNAPLGTVLDQYVSSWPARARR +RAKFYFDGTRVSFDQTPADLDMEDGDVIEVWT +>A0A6J2M367|unreviewed|Small ubiquitin-related modifier|taxID:89673 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A9Q0KJP7|unreviewed|Ubiquitin-like domain-containing protein|taxID:273540 +MGDSPLPWSIEINHVVALEIPCAGHPPEKEKDSLILSLKFQKGKMLIKVMYDHCQMDQGYLVKVLPSTTFFQVKQKMKYV +FGAQVQRQTLRMNGLELRDDYDVEFYELVEGSEIILKYKRLPSGKKLRLTVITPTLEHYQVEVEENTTVARLKKEIQKVS +YISAEQMTLFYFHNEMEVDDYELSAYFVSDVPENARSPCFFWFQN +>A0A8C6TPL2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:47308 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGHC +>A0A7K8C2P7|unreviewed|Small ubiquitin-related modifier|taxID:156170 +QEGVKAENEHIDLKVAGQDGSVVQFRIKRHTPLSKLMKAYCCRQGLSVRQIMFLFDGQPIKEADTPAQLEMEDEDTIEVY +QQQTGGGC +>A0AAD1SJE8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:61616 +IRSVQVTYRSGRERTEILKKTPDNGPWKVAGQDGSVVQFKIKRHASLNNLMKGYCERPGLPMRQI +>A0A6A5TYJ7|unreviewed|Ubiquitin-like domain-containing protein|taxID:147558 +MSDNGSPQQQKPEDGQSEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCDRQGKNPSSVRFLFDGQRVQPTDNPETLDMQ +DGDTLEVHQEQIGGS +>A0A0C7N5E9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1245769 +MAEEEKASHTGLKGAKVTENIQELMSFSDANKTIGGYLQDDQTPEIVHSERAKLPRFSSTIQPNNEEDSSDTAENLEVVE +TDDDDQTKAGNDDKNGVNGPNKESSNQIEVSRNKETDAGHKIDEYEEVQGDDDHVDDDDDDEDDDDDDFFCGDYMLSSRS +VDNSISDRPVIVQTERGSSSVHNSRTGASKLQNASFQTSERDEIVINTSESDQSGSEKETVIKSKKRVASSIKDQDLGTK +WLSKKTRNTNDHNGFQKESTISMAKGSEEDEDEQFFKELAREAGRSASTVEKSPSLPVNHIFNIRFTSHLEGSMDKTVKL +KVNGFHTFTQILPLALNLLLKEHNVNKELRHHYQSDKVSIYRGGVKILDFMTCNSLQVSTDPDIKFIEYSLTLVPKVSEE +DYKTTLEKKNQSETSLLADDPTVDANDTSFFSGDDDVYNSQNSESNHIYILDDDLSPEDQASTTRIALMAKNNEKTHVNV +HQDTSVATLSNHFRSVHNVPAERHIDLYFDNEKLAPSQLTRELDLEDEDIIEVRLI +>A0A1W5CS56|unreviewed|Ubiquitin-like domain-containing protein|taxID:136370 +MFTETSAEGASKPAPFKKSLFNKPAWSKPQTPGDPLDFFHRSRQTYVDIAAEEERKRKRRLARKDEERARVANTEEREGK +RRRVADYSDDDDEQSSSGSDYGELAKPSAPKVQPVDGQKSPSPKRQQISPKSLLKQYEEIASLPEYKEEQESTEPKPSQP +HIIDLEEGESPPRVIYEEDEPEITTVTAVQPPQDEDDALLASDEEFPELARKAREKARQKRLEAEAASATLDPSQSNTGE +GSLQRSLSLQQPTPSPQQTDDIVSILITSRIANTTPLIVNRRISQRLKDVRVTWCGRQGFTPEATVTVFLTWRGKRLFDV +TTCKSLGIGVSADGTIVMKGEKDVLSEEERQIHMEAMTEEIFEDYKDSKRRAIADEDTEEGEKQEAEETEQKPEEQVRII +LKAKGLDDFKLKVKPSTPISKIMNAFRSTYGVEADKEVFLLFDGERLERGSRVGESDISDMDSIEVHIK +>A0A4U5NR35|unreviewed|Small ubiquitin-related modifier|taxID:43335 +MSASAGGGGGGGGSGQEEDKKPGGDQSAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVEFNSIAFLFDGRRLR +GEQTPDELDMEDGDEIDAMLHQTGGGHASLD +>A0A2T9ZIC0|unreviewed|Ubiquitin-like domain-containing protein|taxID:133381 +MDPSNETSKSEQKPEDMKGEAKQEQSATEHLNLKVVGADNQDIFFKIKKSTRLEKLMHAYCERTGTTINSVRFLFDGQRL +SPSNTPAELEMEDGDTIDAMVEQIGGC +>A0A8S4ARX4|unreviewed|Small ubiquitin-related modifier|taxID:238744 +MIAFFLQEAVKTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQVHLKL +KTMSTCSEPITDHRD +>A0A4W4DQM1|unreviewed|Small ubiquitin-related modifier|taxID:8005 +EPDEMTNMKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINESDTPAQLEMEDED +TIDVFQQQTGGFV +>A0A0F4GA09|unreviewed|Ubiquitin-like domain-containing protein|taxID:1047168 +MEYQLPTANDADANGNELPPPPVTAAAANDTEGPAAPMYHVVTLREQNGAELQFKMKTHMKFSKVISAFCDRTGRQPTGI +RLLFDGERLTGDSTPGGLEMGDEELVEVHEEQIGGGA +>A0A1S4AEA0|unreviewed|Small ubiquitin-related modifier|taxID:4097 +MSQTEEDKKPSGDQAAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEMED +GDEIDAMLHQTGGSTV +>A0A8X8WMI0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:180675 +MDNSNDEFEPLFDYTRVQPASVICLDDDLDGTPDFASKKRRISDTTDEKKQDVNSKDVKVIDCGGKEEEEEDWLPPPPKN +LDADSKSIGEDSTLKALRLERQELASFARSADDVVRAVEESVRKDLSASLQSSPKSVAKQPVEPQRERAKLVISIQDKDE +LKQFRVYMSCILKLIQADDKFERLFKIYADKTNLDVKNLVFCFDGDKVTPDQTPTSLGMEESDILEVHVKSS +>A0A7S1I774|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:73025 +QCSPIVVPLSECLFFFVSYLFMPILDLTSAMTYHPPTKKQKITHTTAGDVLDAQSAKEEDAMEVAVQVPDHGTQQCSPIV +VKDDMEAEVPDPQPIDQKKRRRQQKGAEEGTQISVIVSNHDFLEVAHFIIKRSTPLSMLMDAYCQKKNVNRQDLLFSFNG +TRIQGNEAAIDYKMKDGDVLDAQGLPVLLDVQVRWDLLFNFDGRLAEEEEEEEEEEE +>A0A6J0KX47|unreviewed|Small ubiquitin-related modifier|taxID:3726 +MSATQEEDKKPGEQGGVHINLKVKGQDGNEVFFKIKRSTQLKKLMNAYCDRQSVDLNAIAFLFDGRRLRAEQTPDELDME +DGDEIDAMLHQTGGVASGGMYLF +>C1BH81|unreviewed|Small ubiquitin-related modifier|taxID:8022 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHIPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGGSFLSKASLKGVWTL +>Q9USX3|reviewed|DNA repair protein rad60|taxID:284812 +MDNLDEDDLAFFSKPIKKPPLNYAKQLIASSSDSEEESELDTNKQALEHINAQKNITHNENKSAEPLSRQSTILDADEGN +QDVSDTTPNACLNEGRHSPKSAISCVTQPVSPVYNTRAAANLRNNSINSEAALSTTSSLLDDDFARRLEEIDRQVQEFEK +SSSDMDVQIHTHKREIEEDDDNTSADVPLLKHSKSDHSTLYHSKSEFSTNEPVISVVLQLAVIGQRIPNSNISLPRDWEA +PLFFKVKSNQQFRRVRIAYSERKKVDNVVLVFQNQRLWDYGTPKGAGMLKVDTRLVVHAYCHSDFISLKRIKELEVEKLS +SVTEDSTAQTCKLITLLLRSSKSEDLRLSIPVDFTVKDLIKRYCTEVKISFHERIRLEFEGEWLDPNDQVQSTELEDEDQ +VSVVLD +>A0A670JDQ9|unreviewed|Small ubiquitin-related modifier|taxID:64176 +VANLKIQGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDED +TIDVFQQQTGGMC +>A0A7S2C8Y1|unreviewed|Ubiquitin-like domain-containing protein|taxID:327968 +QAQFCRPLPRVVPSPSSFSEAAMGGEGEAGDAPGHIQLKVKDQQGSEVQFKIKKSTPLRKLMDAYCSRLGLQASQVRFMV +DGERIAPDDTAEKLGLEDEDLIDVAMEQTGGCA +>A0A9D3UXJ3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:47602 +MKLNQADSTTDDLEPLFDYRRVQPLNIVCLDDDCSDTSPVPSPKRRKFANPDVAEVDLDKDVEVIKVVNVEEEDWLAPPP +VVSTKAYSKIGEDSTIKELRLRKQELLSFAQSAKSMLQEVEESAKQELSGSLNPSLDAVAEQPKNPAPERAKIVISIQNK +DEIKQFRIYMDDKFEKLFSLYANKAKLDLQSLVFSFDGDKINLAATPASLGMEDDDIIEVHEKKS +>A0A8C7CJN9|unreviewed|Small ubiquitin-related modifier|taxID:8019 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQHTFSSNYSLEPSWL +>A0A1W7RD93|unreviewed|Small ubiquitin-related modifier|taxID:8713 +MSDQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTI +>A0A7J9CDU4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:34282 +MPRSAAAGSSGGDDKALTTAGGQSQIIQVCVKSQNLKQLFVFLGFTGFTENIGYEYGDVSETMYSDTLFLSDGNKVVYNI +KRNAKLIKLMHAYCRKKQLDIHTVRFIYEGHRVPGKYTSDQLNLEDGAEICCMFHQSGGGVHSMPKITSAFI +>A0A8S1KW09|unreviewed|Ubiquitin-like domain-containing protein|taxID:5886 +MADQSQAEYLNLKVKSQDGEEVFFKIKKATQFKKLMDAYCSRQNLQIQNVRFLFDGERILETQTPADIGMETGDEIDVVI +EQVGGWKIM +>A0A317W4D3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1448314 +MADSGEAPAAVEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKQPSTVRFLFDGTRVRPEDTPDTLEMADGDTLE +VHQEQIGG +>A0A4S4L1W8|unreviewed|Transcription elongation factor|taxID:167371 +MSDEEQHPPAQDEHNEEQVPKTEDANAPINIKVVSAAGEEIFFKIKRSTKLSKLQAAYASKVGKEVGTIRFLFDGSRINE +DDTPASLDMEENDTIDVMVELDTKAYVGIDRQDWNSRAEQDMSDVVELKKLAKALQTGTPEILKKDAVVTESALRQSKAG +LAVGKLRSHPSKDVADLAKELVKKWKTDVQKQSGPAKVGSSSSTANPIPSRKASVADSIASPTTPIGSSFNKGQGRSAKT +DGVIIKVTGDKTRDKCIELIYDSLSFDSGAPNDLILEQATSIEAVVLSDHNHDTGKDYKGKIRSLYLNLKDKNNPSLRND +IVSGDLAVSKFCRMTSQEMASEERKAADKAIQEENFHKSLGAEEQQAETTAFQCGKCKKWETRYRQAQTRSADEPMTTFV +TYVSLVTHQRCIRIYYSPPAA +>A0A0K6FZN7|unreviewed|Ubiquitin-like domain-containing protein|taxID:456999 +MADATPSQDAKMMITITHSKGAAPDVKVAVKKVSQLRKVFVAAADRFRTTPDALVFKYNGNVLEGEHTPKMHEIPEGGII +TAYPVDDDDGTQNLQNTQVSMDAFGGDAMDQDVPSPSAKNDKITLVIRSQEGPSFQIKVSRVKALKSAFDKAHEQFRKAP +NTFRFFYNGTRLQDDDTPKMHEMENNDEIDANIQQVGGAFLG +>A0AAF0XI85|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:79200 +MADFYFTMNRDQPLRKLMLAFCERRKQGDYRSLRYHLNGDRIRGHQTPNELELENDDVIDAWIEQMGGAGFSWS +>A0A7S1YIF0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:210454 +DVQVVVPATRPSMTVPSSQPVIQPKIDYGPTMRLKLRTTVLVAGVATGKTMEDYMNIGTREPLRKLQDRYRQAKGLNEDS +RVVFFRGHDRLNLTKTPDALGFEDDAVIRVEAPPPKKGPNKVSPTASAPKADLGQRLSLYLRDPKGERCLVVTRTKAPLT +KVIEKFRKQRKDIGENAHVTLFFDGETMNLSTTPESHDLEDEDLIDVKIR +>A0A022Y5U7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1215331 +MADLPPQSMPAPVEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCERQGKQLSTVRFLFDGTRVRPDDSPETVSVPAGSA +>A0A8C8YNU6|unreviewed|Small ubiquitin-related modifier|taxID:1328070 +MRVKTENKNHINLKVAGQDGSVVQFKIKRHTPRSKLMKAHCEWQGLSMRQIRFRFDGQTINETDTPAQLEMEDKGTNAVF +QQQTGGVSSHGDVYL +>X6NLI0|unreviewed|Ubiquitin-like domain-containing protein|taxID:46433 +MSRSPHPNSESNANQASNQAPPANESANDGTNNTTTPGNDASAEHLNLKVKAQDGTEVYFKVKQTTKLKKLMDAYCSRVA +KEPGSIRFLFDGERIQPDATPQQLGMENEDEIDAMVEQQGGML +>A0A8E2EXM5|unreviewed|Ubiquitin-like domain-containing protein|taxID:574774 +MADSATAEEAPSKPAKRSFFKKPSWATAESKSESPQTPIDVFSHSSESFAEIIAEQERRKKAKLRKKQEAQKRKENEGRE +NKRRRISTEAEEDRHSLSPTSSRRRSSKDRSRTPHDLTAVINSSPKSAKQHINSQSLAARHDEVAKTSNSPKKQSVVIEL +SDSCNSSDDDLYKPPTPIGVIVPKIQRAKEPQDEDDQEVDPEFRALAAKAREKRRLQELGATEPTGSGGPSRTSSSFSRP +ALAASPPAPDPIVKIFISSAIPDTVPLLVSRKLSQRLQEVRKAWCSRQNFSEDMADSVFFTYRNRRLWDVTTCKSLGIEV +DSSGNIRQKDDLDLYSENDGRIHLEAVTMETWEDNKRRAGKAHTEEPEEEEQDIFEYEPAIEEPKFRLFLKARGYEDFRL +QVNPTSTFESIAHAYRVSLKIPSDKSIFLMFDGDRLDPEDTMENSEIEDMDSIEVHIK +>A0AAD5FFK6|unreviewed|Ubiquitin-like domain-containing protein|taxID:30991 +EGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQVKTFSTTLIIISSSLWSSGVKQEVEKMDGCWFVVLD +RGLTMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTGGV +>A7RRX5|unreviewed|Small ubiquitin-related modifier|taxID:45351 +KLKFVFQDNSEVHFKIKKTTQLKKLKAAYCDRQGVQMNSVRFLFDGQRINDDQTPKQLEMEDDDVIEVYQEQTGGL +>F4K3D6|unreviewed|Small ubiquitin-related modifier|taxID:3702 +MSATPEEDKKPDQGAHINLKVKGQAFFVVGTWLVIDTDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLR +AEQTPDELEMEDGDEIDAMLHQTGGGAKNGLKLFCF +>E3JR90|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:418459 +MAKRKSSTCQPTTTSSSRRTSSRLAQKNDPNYQAPLYQPLATQPTHNSTTTNNKNKNNKNKNKNTQLTEQMDTPNQHQVP +LADHSRGDQEQPNQLSESNNQPESNNNHQITDSENKKDLHNFTEIGISPMDMNSNPAATETPMETNQEITPQNIETREKH +PENYHQSNSNGQADHHQPDIPNQTDTRPDHNHVQVANNGQENTALVNQQDTSINNQTDVNQDNDNNNQQSDRVAFSPSPS +PIPQRRPKRAPPRSPSPTPPAPATPSHKRAPFSPESSASPIPVRSSRPRKAPPSKLEEEEEDKKQECIGRNRSSDSASRE +PSRPLQSPSKRARQTSGLSDHTTPLSPRPQDPKMENDNPSPHINQPHPPQNKPVPPRPRPIRAHRPIKKIPPPAAANRNP +NDDDEGDFFNLSSRQPRHFVSKTLGLTKHSPAPSKPSTSKSPTRSSLDPPAQKLNLVDLSGDENSNDDGDDSDDMSEDDC +KNKKRLSSRPLPTWTRASQILAAESLSAEENEGSNQADDQAKRSRDGTDQKPRNGAKRAEKSPAKSRSPTPPPAPDEQVI +RKTMKALYQTLTQQGHASSLQKQAAEAARKVEEAQLIQTLNGLDDPTIPDTYTTVNARGLNAHRGPNRAPANHALGTPIT +FTINMVMDPRFAATATLQTKEHYERPIHFIMQSGEQFDVVYQRFHEITGLPADQLVVSYDHIKLSPFVTPESVRIYGGNT +ALKVYESSAWEYVSDLRRHRAQKPRQADEEEVLREELKNLPIGSERGRSEATEVPMEGADGGAEPQESVVGLINLTVRTK +DKQKVELSVKPSTSIRSILKNSLIHLNFLHPSPDPTKFKISFDGEDLPFSSIVSDHDLDHDDVLDLTVL +>A0AA39W2Y1|unreviewed|Small ubiquitin-related modifier|taxID:4024 +MSDAAMDPLPNPPPPVVKTEQAEKNNNPSSSNHITLRVKDQNQNEVYFRIKKSAPLKMLMDGYCVKNRVEFNTFAFLFDG +KNLRSDQTPEEAGLEDNDEIDVFDHQLGGCIVG +>A0A372QKV4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1803374 +MAFDDQSSSQIIRTDAVDPFISLRVIGNDRNEMTFRVKKTKPLQKLMEIYSERNGLSIGTLRFLYDGFRIKNDDTPESLE +MENGDAIDVMVEQTGGGF +>A0A6P6MHD0|unreviewed|Small ubiquitin-related modifier|taxID:7957 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGHV +>A0A7S0AF97|unreviewed|Ubiquitin-like domain-containing protein|taxID:73915 +MESTRTRDVRAGFSEPPPPEEPAALARKAALEARRKAAQEAQKAKADAYAKQRAQNQVERRAKRQAELEQQRREEEEARL +KAEEEAKLAAAEKQRADEEARRKAEEDARIAAEEQVRAERRARVAAKRAAVQAAEEATRREEERQIRAAEEEAKRKADEE +AAKLKAEMQAEAETAALLARRQAAVANRAARQLALRKEELKAKWQEKLAAKRRAEEEASLPEEVRQQRAEARRQEEEEDA +RQRAAEEARQAAADAAERLASEKAAEKARLKAEREAKYQAVQELRRLAEEKAARKAEEKAQRDAEEAARQRAKEERRQAA +QARQGTAAGAEAEEAAPLPAGSLRLRVRNELGQEVELRVQQDARLQVLMTVACTRLGLQQAAAQFTHHGQQLAPSDTAAD +YGLEDHDLLEVTEAVR +>A0A168KS51|unreviewed|Ubiquitin-like domain-containing protein|taxID:1081108 +MADLTKKLPFKPTALRNARPKPTPSSSTEDDALQASVAAGYGRSDDSDDKQDTLAMFRRAKEMAPIIEADRERRMRRQQQ +KQQQEQEAERRRVSAGSKHSLVAEGDDVAGAGAGAGAEVAKTTTTPTPTATQTSSSMPEDVIMVTQEEDNRYACRRLMRE +TLVQTAGTDFMHRELVTPPPSKRSRRDTSGSSTRHKDVDLNSNNNTESAPDSPTMRAMRSLAPDRSITPALYNTSLYSSG +GIASASTMYKTRSQTREGVAPPLPPGSQVIQLDSDSEPETTTPAAAAAAAAPVEIIDQALTLDLDLNADAPEDDDEFAEY +VRKAQEERDKLLLQKEQEAIAAGTITPTPTPASQPPPTGLSSPAPASQTAAAAAAASAATQSIALIITSDIPDSHMCLVK +FRFDRPLRVVRDSWTALQHKHGVPLRGLLDRDDDVILTWRRKKVYMTSTLLSLGIRPSDDGSGAALVDGYSRDGFNESRT +RVHMQAWTPALFAQMERDEEEAARRRRSHDDDDDDNAAAAGSTQGPAAGEGENATAAAEEEEEEEEVQLRIILKSRDKDP +VKLRVRPETTTETLVAAFCAQRAVPDSADVGLWFDGMRLAGGATMEDADIDDMDTIEVHVR +>A0AA35NPZ3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:230603 +MTGNSKDSGSALGNIDANNTSLSDDDSDDFFMDNSFDEIDNNQSDDSNERNVIVESKITDSQPFHLSLPSSEDEDKNISQ +RSLSDSESASSANIVKPKSDKPSGRTRGRSVIKESVVEIDSSESKTKKKEYPHRSRSRSKSSVRSISPEQKYKRQKNSLL +NTYDENDDFFKELAKEAKKTTSISKESTPDQPKRVYNIKFFSKLEGTINKAVQVKVLGKYEFSRILPAALDGLMKSYKIP +KVMKDIYKEENVTLYWNNAKLLKFMTCNSLHIPQDFENEISDIDITIVSKEYEKNFEATLESKLKEEETALFAKERQEME +MKLEKKRNEREESEFREFEFELRNVEETEELKANETFMNEHSLREGNSVKENNGGNEKVMKIALMGQDNKKIYVNVRNST +PFFKVAEYYRIQKQLPQKARIKLLFDHDELNLNECIADQDMEDEDMVDVIVE +>A0A6A5F0U2|unreviewed|Ubiquitin-like domain-containing protein|taxID:8168 +MAIDRALQPSQYIHEPSPRKVARQIDSAAAAEQAHTDAGAAMADEKTKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTP +LSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMEDEDTIDVFQQQTGGSSL +>A0A9P4LU02|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314787 +MSESGSPKADAPPQQTEHLNIKVTDGNNEVFFKIKRTTALKKLMDAFCERQGKSPTSVRFLFEGQRVNAADNPDSLEMND +GDVLEVHQEQIGGAC +>A0A670XVU2|unreviewed|Small ubiquitin-related modifier|taxID:8673 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGMN +>A0A225AGH8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1441469 +MAEAGGDIAPEPVEHLNIKVTDNHNEVFFKIKRTTQLKKLMDAFCDRQGKQPSTVRFLFDGTRVRPEDSPETLDMQDGDT +LEVHQEQIGG +>A7WLI0|reviewed|Small ubiquitin-related modifier 4|taxID:9823 +MADEKPKEGVKTENNDHINLKVAGQDGSVAQFKIRRHTPLSKLMKAYCERQGLSIRQIRFRVDGQPINETHTPAQLELED +EDTIDVLQQQTGGVY +>A0A5N4E4P1|unreviewed|Small ubiquitin-related modifier|taxID:9838 +HVELLPLYILFFQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRI +ADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0A8C6L8G7|unreviewed|Ubiquitin-like domain-containing protein|taxID:105023 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQVRSAVAPIAARFFTLNQTKRNSTNP +NVFMCPLVLLSQGVPASTLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTGGFWND +>A0A665W428|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:173247 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQLGMEDEDVIEVYQEQTGGLWND +>A0AA38VJ67|unreviewed|Ubiquitin-like domain-containing protein|taxID:91930 +MADAPESPNNNGGGGDAPPAAPEHLNIKVTDNNNEVFFKIKRNTKLEKLMLAFCERQGKTLQSVRFLFEGQRVQPSDTPD +TLEMADGDTLEVHQEQVGGC +>A0A7L0L5W6|unreviewed|Small ubiquitin-related modifier|taxID:208069 +QEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDV +FQQQTGGVY +>A0A6A1PXN4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9770 +MADEKPKERIKTENNDCINLKVAGQDGSVVQFNINRHTPFSKIMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEV +>A0A7K8V578|unreviewed|Small ubiquitin-related modifier|taxID:1118524 +QEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDV +FQQQTGGVY +>A0AAD8T2I3|unreviewed|Ubiquitin-like domain-containing protein|taxID:4521 +MSSPPPESVLENEKETEASPGSVHRKEAETSPGSGHGKEAEEVILKPVKPEAGAEDGVHINIKVTSQTAPEVFFRVKRDL +KMQRIIDMYCGKYSLLPKTVVFMNEDKYIRADQTAEEAGLEDGSTIDVHMSQLGGSGRASA +>A0A5J5CTE9|unreviewed|Ubiquitin-like domain-containing protein|taxID:54343 +MADEKPKEAVKTESNEHINLKVAGQDGSIVQFKIKRHTPLIKLMKAYCDRQGLAMRQIRFRFDGQPINETDTPSQSGSNA +GGMGLVGWHRRTHGSGLRYVQSVSGGVFIPSELCGEGGGLVLRPPGGTSSISFGTDDNSTPRKDKMASNIFAEPEDPHAH +RRNNPPTGAAAGTICGEPSAPLRRCQQPLLFPKNPEPELTTIHNSGAALVWNQRREVVNGQEPANDECPNNVEVEQEEPE +QHKETTEPAAPSGGANAAAGSRRNPPGGKSSLILG +>A0A8H8J1C3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:170446 +MSATTTTAPPKPPPTGPPPKPNGVTAQQRQQTRKNVNAGNPNVKVEPTAPPDPVTMYESVRNRIAALEEAEVTGEEEERR +HAEEARASVRGAPDSVIQTKYIELFQEMKRLEREHAKERQKLTKDKDAAKTQYNKLSQAKTKVESLARELQKENRKLRED +TRGLTLSFEKARDEINQVKDELVQRQLARPPFFARKPLQENGAQQPADIVVKVVCKFRAELFFKISRKTKLTRLFTAWES +RMEVSPEPHGKKQSRKSANFIFTHAGRTVDWDQTPDEAGIENNDVIMAVELMDLTLADSEENPPKKPLLKKFPLEEDEAE +RAVEEMYDAVVRERLKDVLRRYELREKHFEAVVRSKELEVLLARARVEEQKGCVEAARRVARAAEQQNAALQAELEDMQL +QEAVVAGKIQQCLQALGKSSLTDPSPAAARIVRDVLREHLEMRARTIEQNANQNSGDDAS +>A0A257B0J0|unreviewed|Ubiquitin-like domain-containing protein|taxID:2012633 +MSDVDITFRNENNGKEVEVTVSDDMTADAILRNLVEAGVIPNIPGATLVFRNMQLRPNQTLAQAGIVSGDTIGIFLNTRG +GSAERRGQPAMGCPPRPLGA +>A0A337SGX9|unreviewed|Small ubiquitin-related modifier|taxID:9685 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A7L3XKB9|unreviewed|Small ubiquitin-related modifier|taxID:1323832 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0AA36GM22|unreviewed|Ubiquitin-like domain-containing protein|taxID:53992 +MALSESISSDSDDDLYTKSIDLEKVKVTPHNDILPSNSTKQESRQIGSSVAEIEVIDDDASLDLPDTEQISQRAKEARKK +RIEQLARKELLELEKIISEPALGFIAPYPKRTKRVNCSKDTQEIGSGNHGIASYFKEAPVAAPDKSTDVYDLAELDKEVN +LYVTVFVDKDVNRKGRFMTLLRDEPFDKLRPEFARELKCNQLDVMIHVNNVDAGPGDTPDSMGLDIDKLAVVNVFSLRSE +EGVGTDFSTDPSFIPVKCIFASGRPRCVYIKLTETFEEAKKRIKEALHLPGTIEKLVFDNDVLEESETPESTEMEAEDVL +EVYLKTS +>A0A7J6GNG2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3483 +MSVLGQKRKCMDQEEENCDDDQRVSIKVVSQGTANKETYFKINKKCRLFRLLQTFCNHQNVDYRDMQFLFNGKRISPKHT +PHSSSKLCKLIDMLKMKDDDQIDAMMHTDGGGSGCDRGGNNAF +>A0AA88UM26|unreviewed|Small ubiquitin-related modifier|taxID:112253 +MSAAADGGGGGGQEEDKKPSDQAAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVEFNSIAFLFDGRRLRAEQT +PDELEMEDGDEIDAMLHQT +>G1U7Y7|unreviewed|Small ubiquitin-related modifier|taxID:9986 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINESDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A2R9BXY3|unreviewed|Small ubiquitin-related modifier|taxID:9597 +MSDQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0A9N8PT70|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2773716 +TRPKRMADGKPKRSLFKRPTWAAAAPAPASASPDPTAKPEAPTDIFSHSHTFSELVEDRQRQRQRKKSDKDVLRRSQAKE +VKDEESRAGKRRRISDEDGTELPTKPNPKDTERKTSIQVSAGSESFAIAPTPQKPRPRQETVIELLDDSDDDEPVSYNNA +SHNITSSNATSLEPIPAVEADPDADLDAVYYSDPEMREFARQAREKRRREERERTETGAHDPTVKLLITSTLPGTGPLIV +SRKLSQNLQAVREAWLSKQSLDPSTASRIFFTFKLRKVYDVTTVRSLGIKVDSYGRIMTDGPXANTDDEHAEKIHIEAVT +DEAWQQLKDEKAARDAPKPNKYLSNAAAADGRGASTEGTPAVEGKAAVEEPLIKVTLKAKGHSDIKIKVRPMINAARRSF +KLDAERVVHLEFDGERLEPPEGLVKDTDISDMDCIDVHIK +>A0A8K0MP85|unreviewed|Small ubiquitin-related modifier|taxID:2594499 +MSGVTNQEEDKKPNDQAAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRAEQTPDELEM +EDGDEIDAMLHQTGGAIPAPVEGYI +>A0A5N5GZT0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2448454 +MEDFSEELEPLFDYRRVQPVSLICLDDDELDAPSASPPKRREISDSAIEKVDEPVKLVSVISCEDKEEEDWLPPPPKVSA +GAKRKGEDSTIKELRKKKKELASYAQSAENVLRSVEESVIKELSISSEAVEEQPPKPRPERNKIVVSIQDKDGVKQFRIY +ADDKFERLFKMYADNVKLDLQSLVFCFDGDKIGPAATPDALGMEENDIIEVHVTSR +>A0A7K9UY25|unreviewed|Small ubiquitin-related modifier|taxID:8851 +QEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDV +FQQQTGGVY +>A0A8H6B9T0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:5007 +MPLAKPEDDFFAFGSNDFDMTPPKKKLKKEKKHHRHHRHHNRTQKQIESPKAGRTVSLRSVSSSSDPLVSDIEPVKAEKM +SSLPQGKIEKSASRSKHPLLGLNNDNDDGVEYPASSYDFRSEPIVSYDDDLNQIQTEDESILNQMDSEISEAKKYDDGLW +KKRGYKKEITGNFPVELGGQTILAKKAPFEITVSLRYQEREFSVFLKAKGSTSFQKIRETVLKQVFRSNTLWSFTSSPEK +LVFFIYDLDIIVNQVLRIGSLLRSSKKKVERSFSDDSFVLRTMLAPMGIALQIQAEEKQKKANSTILQGDPGDHLDESIK +STITIQLKDRNTGKITRVSTSRSTTIESLENIFLVRMKYPDGLRVKLYGTSGEFMGKELSSVREDKSKKAELEVQPDIAE +ETKESIAEIGKSNFKRPEVIKLDDFSDDEKEATNDEQEVQKTLKDEVVELSKPKYMLVPTTVGFYKLEDQDVVELEYSQE +ELAKLSESLQGDSRNEEDDNMDAKGLLDNLNMKNDTYFGIKLVGKDGKVYQVGVKPETSVQSMIEYYRKKANVPERTHIS +LIFDEEPLDPKWKVSDTELEQDFMVDVVLKYGCVN +>A0A015JG82|unreviewed|Ubiquitin-like domain-containing protein|taxID:1432141 +MDQLSPQFIKTEAVDPIDSFISFHVKNVLRTTPFKKLKEVYCKRNRLKIHATKFLFDGLNVMDNDTPDSLEMEEGDSIHV +IFAPAIR +>A0A5N6MXI0|unreviewed|Small ubiquitin-related modifier|taxID:192012 +MSGVTNEEDKKPAGDQGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVELNSIAFLFDGRRLRAEQTPDELEM +EDGDEIDAMLHQTGGDGGFLWL +>A0A5D2K9M2|unreviewed|Small ubiquitin-related modifier|taxID:34277 +MSGAQEEDKKPGDQSAAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEME +DGDEIDAMLHQTGGTSA +>A0A3F2Y3V3|unreviewed|Ubiquitin-like domain-containing protein|taxID:5007 +MSEEPKSEPKDSHINLKVTDGSSEVFFKIKRTTPLKRLMEAFCKRQGKSVESLRFLYEGQRLTPDSTPESLDMEDGDLIE +AHREQVGGAFY +>A0A7R9J4H3|unreviewed|Ubiquitin-like domain-containing protein|taxID:61474 +MNGSRIGKVELEEVNPQCKTIMGKTPPVHPTEIQTSISPYSEVELNMSSTLANYTTEGVPVTSLRFLFDGRRINDDETPK +QLEMENDDVIEVYQEQTGGQF +>Q94CF9|unreviewed|RSSG8|taxID:4530 +MLLMGDVDVNEADPEGNTALHWCLSGSSSTQEPRIVWLLLKNGARVFQGNKLGLTPVHSAAAKGNYKALQSLLLHAQDCV +DTPSKTKETPLFLAVKNGSLDCVKLLLRSGASTKVQNLRKQRPIDVATSQDMHFILTSANVVPWNRSSHPKKIVTNKESC +KEFLDDNFVDYDSDDLNESFTGLKTSASHRDFRSSNGSAQGGKSKNHCAPKQGSKFVPRPNHWLKHDYTRKIFVGGLPLS +VGAEYLTEFFTAEFGPVEEAVVIGIRMGDRVQSRGFGFVKFKREEDVISAKETHHVYMLGKRVEVKDAVARGFLPAEIQK +TASFRHHSQEVPKVAHHMLDGELKEEHYIRKWRPLPEKCLPSWFFIFRKWLPGFLADATERLGDRYPLSSLKGDFRAICR +MELDHGTFGYPKLSDFMRSLPGICRMCVVPVGSGPATHMVLLPPVSRPKYVPLLEPFSFDHDELPESVSDHQSPRSPLTT +NITEDSLRNTDSQKGDTCSESNVQSHQGDECCGSNTESQQYSASTDNGSLPSEVAFGTTDLVELVQTREHDLIAPASTRR +FDFLEPVSTREPNVIETVSLNQKIVSEPLTDLLQSGHTRRVGLIDSRSTCLGDFLVERVAEIPTRHINEDSNAQIFVVGC +HGQLTLHVDLKKKTSSMIQAYEEKTGINHEYQYFIYERKVIDPDDTLSCYGIEKGSTIHACSRLRGGASMTLGQYLNRYK +DDLLEDVILPDGRAYPVMKPEPSGVLRSWLKCFTTAFSKGYCWGENFLLSNFKVVNGKVEVIKEAKHQIRTDFLQAHLRK +IDETIRWYFCRDGERFPPYLDELCDFLKLRRGLVLSEDAKEFIDDHVCFMNSYERGMLGIKLYKKLNSLSPGQKLKLLRA +LGKIAWDLSLMDDVDKLPLLCDIIVQAKAEGKPFPRTILGGFRLLRDYFAHIPEHQYDKATKPWKRKFRIYIGIELMIPV +HLKKLLPRIIKCFLDAKIDIKRELLSSHTMRCSICYSAGTSSTVPRFSATPETRQTAGGITKSINELGTSSKAVASSTTP +QTGHATKGTIGTSNELGTSSKAVGSSTTPQTGQDTKRTTRSSNELGTLSTAVGFSTTPQTGQPTKGTIRSSNELETSSTA +QRNTWSTGQAARNLFAHSSGAPSAVQQQSQDDWETVQKRKG +>A0A8S3HYA6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:392030 +TSSSADTIEPVNPVKSSLLKTITLIIDHSDGRQLNLSVPSSITLKSLSEDVAERLSLPSIYLVYNDQTLKLDDNNQSMTL +QQLNFSSNDTQLESYPLVRKINIFIQTSATSARRSSFVSKREYTILDTDRFEIIFDAYKRDMKTNNIRFEFDGDTLHPHA +TPVDYDITGGEILDAFILPTSNNNNNKQKNELKAKKAKEIIF +>A0A9D4B7M4|unreviewed|Small ubiquitin-related modifier|taxID:74926 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLNKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A9W7MCZ0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:183268 +MSQTGSNGGGGGGAGGSGSGQIINCVDRSQRRIVIHITGQDGTRLTFTIPRKLKLSVLFHNYCTRKQFDYRTARFFHEGL +RVLGRYSSAQLNLEDEAEINCMLHQTGGGF +>A0A673N255|unreviewed|Small ubiquitin-related modifier|taxID:307959 +MVMKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQ +QQTGGSC +>A0A836LKL1|unreviewed|Ubiquitin-like domain-containing protein|taxID:2803181 +MENQDHSNQHPEGNNNNNAAPAPVKAEAAAALSAQQISLKVVNADGAEMFFKIKRGTQLKKLIDAYCKKQGISRSSVRFL +FDGAPIDESKTPEDLGMEDDDVIDAMVEQTGGSVMRHL +>A0A7S4QKA5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:311494 +MAALTFGALAPALLLLLLLASAVGAVDDSVSAVQRHVQSAQSSGVRRAPPESPAEASTALAERKAALEAQRKAAQERIKA +KAEAAAKLRQEAQAERRAKRQAELEEQRKADEEARARAEEEARKAAEERRRAEEEAAKRAEEEAKVAAVEKVRAERKAKL +EAKKAAAQAAQEKLKREAEKQERIAAREAKRKAEEEEAQLKVQMAADAERAQEAAMMARRAAAQAKRAAKAEEQKRDEMR +ANWQAKLAAKREAEEEARLPEEERLQRAEARRQREAEEAMRRADEEAAKQAAVEREHAAADRAAKRAQAKAEREAHFQQV +QQLRRQAEERDAQRAVDKAKRAADDEARRAAVEERRVATERARGEEEERERAQEAADQAGALRVRVRGPRGKEVELRVVR +GTRLRIMMTAACGRLGLRLESARFTRGGREVSPTDTPEDCGLEDRELLEVTEVEE +>A0A7S4S4G3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:311494 +MAQETGGSRRFQVLNLLRGHPEPARSSGLMLARVALTALLPLVASGGPATVQPWIGRDDSVSLFQLTRSAQAGDHMGALA +SDAADPQDVRLPRAFQGPPASLLQLLRDDPGLPSGGEAAAAAAPASPGAPAPQASAPASGGEDGTREAPQPAPVERAPVA +QPTDPGAQAPAPGVQEMSSSQAPEAETEAEVEAAPGGAQAVSSSKPVDEEAKRKAEADKYAAELADGFIHLTIKHETGEE +LHLKQKPRADMSIIMRVACNRLHFAMNEVNFTNAGRDLRPEDTAAALGLQDKDVINVKLLTAEEAIAKAQVQKTAKADAA +AKRQADSDAKKKAAEDAKQHAEEVAEAREQEKQRRQAEEEAARQAKMEARRKRDEERRQAAELKAQKIAEAEAARREEAA +AKKREREAAKRQVEEEKARAELLKVQKQAEETARLAAEAEAKRLADEKAQQQAEEEADRLAAEQEKQAMEEKKRQREEDR +VRLKEEHERQKAARLEEHKAEQEARAKEIEEAIRKEQEERAEKKAREEEQRREAKRIAQEEAAAHLAEEAARKAEAAGEV +>A0AA88GVG9|unreviewed|Ubiquitin-like domain-containing protein|taxID:51637 +MPKNKASSQSKKQQAKKASSESDSSDSSSDEDLFHHKAAKSYKQSTWKLSNTPPSQPEPNKKKNLLEMTKTTSPNSKTET +KEEGAKPSNNDDLLLELQVDMYKNELHKKNAKRNTVTDEESKKKRKPTDEELKKIILEQKKQRREQKRTKHTHSSSIPPE +DIISIDDDLTPTTVENATSTYSTIPTSSTNELYGNTGSAFSSSSSMFVRSPAFSNPFRAISPFPSYSPGDFFYERSKNDL +QRKFDTLLQSSSESVFDKLETIDKSATELSEKEKQRLEESLKKQLEELKPELKLDNSTLIDQEEDTENKGEKITIRVRWN +EKIVPINMTEKDKFQKLKKTVAKQFDAHPDQVTLIFDGMPLNLKSTPEDHGMETDDIIDCKIDKSKPISTIITPSSSKKP +SSAIEVIDDASPKITINVRAKDKTFPVKISTTDKFSKVAKYIAKQLNVDVSKVKLMFDGMALNVNETPADQDMEDDDIID +CQVKAK +>A0A3M7G214|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:91943 +MGLFKRPAWAQVQEPGEDTEQSLFSHSSRSHEAILAEQQRQKRERAEKEKKKQERKDHRDSSKRENDTSDYNEQGSNKKR +TLNRRINPKESEDLLSSVGLSPAGAAAKSKTQDPGESKVEEIAQRRSPRAPYTATTEDSRSKEVPQSSTVIDLGDSDGGN +EVQGRQDPPVEPEPISDSESDEEFAELRRRARAQKLKEEEAKRKTQTPDAKSPTPGLDGAGTSHYGLPTPPPAQDPPVKL +LVTSELDNTRPLMVFRKLTQRLQEIRVAWCQKQGFSDEFTKEIFLIHKLSRLYDSTTCRSLGLYIDKDGQIKLKGSEMPQ +DAQIHLEAVTEEIFERKKAEKERQERAREKALMGEPDEEADAQAAEAPKESAAREEANVRIVLRAKGVSQPFKLKVKPST +PFSKIMMACRGHFSVGERQQLWLELDGERLDPDDMIQSTDVEDMDNIDVYIAG +>A0A8C7AXF7|unreviewed|Small ubiquitin-related modifier|taxID:452646 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSTI +>A0A8B7CA28|unreviewed|Small ubiquitin-related modifier|taxID:42345 +MSGAAQEEDKKPADQAAHINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEME +DGDEIDAMLHQTGGGMENVDIF +>T5A7I2|unreviewed|Ubiquitin-like domain-containing protein|taxID:911162 +MRKKRRQDEERRRQSDLLDKRGREDFESLDGLSPRDDQPDLPEQPPRAWGQSTPAIDLSRPDEGEDGFRELVTPPASKRP +RVESTPSNIPILSSDEDDLVMVDSPSTRCGGSRSHLTTPRNKSKQAVAASSSAQAVATMDSPSTRRERSQSHRVTPRNNS +KQIATAPPSAQAILLDSEDDDDSDSDDDLKVIATPPVHPIETGGPLLSKAEEQRARDTALLRSGVDKGQGRETVDILVTS +TVLNAGPCRMKFLFDKPLRVVRNSWVALQRRNGVQLPLLNDDDVILTWRRKKVFIFSTLLSLGIRPQGDGRLEVDGHDRE +GLADNRTRVHMEAWTPELFQEMEQQEALRRKREAGELDESEDEARDEPPTPEVRIRVILKARGLEDVKLTVRPETTVETL +LIGFRTQRSIGSDKAVSVVFEGERLEEHVTMEDADIADMDLIDVHVK +>V4KY52|unreviewed|Small ubiquitin-related modifier|taxID:72664 +MSATQEEDKKPGDQGGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELEME +DGDEIDAMLHQTGGVTNGLCLFCF +>D8SAB7|unreviewed|Small ubiquitin-related modifier|taxID:88036 +MEGSSETPDVKPEKKPGDHMNLKVKSQDGNEICFSIRRNTRLAKLMKAYCERMSVAPDSIAFLLDGKRLREDQTPEELEM +EDGDEIDAMLHQTGGMPL +>A0A2P5WRZ7|unreviewed|Ubiquitin-like domain-containing protein|taxID:3634 +MPRSAAASSSGGDDKALTTADGQSQIIQVCVKSQDGNKVVYNIKRHAKLIKLMHAYCRKKQLDIHTVRFIYEGHRVPGKY +TSDQLNLEDGAEICCMFHQSGGGVCSMPKITSAFI +>A0A9W8VRA9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1237075 +MSNENENGTPGEQAPANSEHLNIKVTDNNNEVFFKIKRTTKLEKLMGAFCERQGKAISSVRFLFDGTRVQPTDTPDALEM +ADGDTLEVHQEQVGGSSQ +>A0A1B8EF83|unreviewed|Ubiquitin-like domain-containing protein|taxID:1524831 +MSTPDPADPFASPPGASSAPAPAPAPAAVTAARKSLFKNRNRGGAAAATTTDAIGFFSRAKDVFAENVEVQRRERERERE +REREMEVQREMEEERVREVERARGGKRERVVKGDEESGDEEGGLDSEGERRRKRSRSGDRSDTPAGESEYGDEESSRSVR +REGSTHSTYSNSIASPGPSQRNTRRQANIISLSSDDEDDKPAPSPGPTYPSAFSSPPPKPRSTNPEPIAIPSSPPAPPPS +DDDELYADLIAAARRAPATTAATPSTAPDPTLTILITSPLPNTTPLLIRRRLSQRLKDVRLAWCARQPPHAGAAATIIFL +TYKGLRVWDTSTCGSMGVKISRAGGVLDDSGGGEGGDVHLEAWTREALEAHKAAEEERVRNAHLALENGDGGIGGGGGGP +AVEVVAEQPVQEEKLRIILRAKDMPEVKLRVKATTRIGDLVAAFRAQREGEVGGRSVELWFDGDRMEEEDCVGDADLEDL +SGVDVVVR +>A0A5C3NW40|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314778 +MCDTFKRAGIREEDKPRVAASVKITVCDQMGRGVIFRIKRVALLSKLQHAYACTVGQDEASLKFLYDGQRIRDGDTPEGL +QMSDDDVIDVALEHVGG +>A0A8C7YMC4|unreviewed|Small ubiquitin-related modifier|taxID:183150 +MELEILFPYIIPLFCGDVAHIEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQP +INETDTPAQLEMEDEDTIDVFQQQTGGRI +>A0AA35JUJ8|unreviewed|Small ubiquitin-related modifier|taxID:74358 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A9P7M8I3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1649127 +MSELPMTPMPPRAKKLPFKPTALRKCATKLGASVAPDASIDCEKAQNEDGLDIFRRSKEMQPIMEADRERRLLKKKQKEE +EERKKAAKEAEVRRKAAEEVEQRRKAAMEREERRMAAKKAGKRSWEDSENDGDGGLARVSPPPTQSPNKAFRSTTPVKVD +ADISDEDPNELATPPALKRTRLSLTPTRTKRLASSDLTSMTRASSILSQAASAIARESPRRRLHSTKPSPDHVLVVLSDS +EEDDGDSDDDDHAPASTPSKTDEGDDVAILGSSFAAEDEDDEFADYIRKAEEQRRNQALTKVSQNSGAPKECIQILITST +VPNINPFRVKFLYDRPLRLVKDTWLAMQTQRGLLRDLEDTNDVIMTWKKKKVYASSTLLNLGIRPPTSSRVDIDGLSLDD +NSTMHVHFEVWTKAQFEEMERAEESWQRRRDAGELSDDDDDSLDHLPEEPAVPEAKLRVVLKSRGLPDVKLTVRRETTVE +TLITGFQTQQASAVGKDVGIWFDGDRLEEHMTMEEVEIDDLDTLEVHVK +>A0A9P0J2D5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:80765 +MTEDKGEDATEYMNLKILGHDNSVTPFKIKKHALLIKCLKTYFKIIGLDRVSVIFSFDGHRIIKTDTPSSLEMKEGDVIE +VFLRQIGG +>A0A6A7AHQ1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1469910 +MTDTADSAPPPKKRSLFKRAAWQDAPKTDGEGDDMFSHANEFDKIVAEENRLAEEKRRKAHERKRKHDGQADRKQRKVSS +DHDEPILPRSGSGSAARATRISSKARSRTPLSPAPSKPPPDSLSARYDTLTKSTSSTSHIIDLGDSDEDDDTGYNLRSGN +GNSLLDYSGWKTDRKQDMAVRPLRPAIPVVDDDDDLEELLDPALATIAARARERAAASARIAANPTTGEPEKAPVIQLFV +SPEIPDAKPLMVKVRIDSTLEKTRLAWCGKQGYSPALTKDILFTWKGTRVYDSTTIKRLGIEIDAHGNVSVQGDNNIYDN +VNLPKVYVEAWTPQLFKQFQEQEAAEAAAKRKAAEPSPEIEARDPTPEPAPKERKFRLTMKAKGKEDFKLYVRPTTTFAH +IASAYKLNRGVDESQPITLMFDGDRLAPMDIIADSELEDMDSIDVLFN +>A0A1I7T2G3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1561998 +MSGSDDDNAYGNYLQSRRAVINKNRQPVRTYESDSDDDFADDKTSKIKRKRADSSFDESDEESSVINVETHQDCFKVIMD +HAEEEYTRKICHNEGLIHVRSIERNDALMKAIQVVKDMEHDVEVAEVEEPGEVVTIPEEKEETADMSVDTLVFAVSVVIV +DCESCLKNTEARLRREVPLESTFIEVRRELADKWKCRPDQVILTCNDTTIDMKTTPKDLGLFPLQVPQRILATKKGGEEL +SRPPAEHTEVITVDTDGSITIKVQIQSRRKPMHVKVSEETTVQELKQKIIDAMIEEGVDEIPSIETMKMMFDDEYLLNMD +ETCESIGLEDADCVDIYY +>G3UDZ5|unreviewed|Small ubiquitin-related modifier|taxID:9785 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVF +>A0A421JNK2|unreviewed|Ubiquitin-like domain-containing protein|taxID:2028339 +MSDTEQPKEEKPDSTTHINLKVSDGSAEIFFKIKRSTPMKRLMEAFCKRQGKDMNSLRFLIDGTRVYPHNTPDELELEDG +DTIEAHREQTGGAYL +>A0AA41N8E7|unreviewed|Ubiquitin-like domain-containing protein|taxID:30640 +MQKSTISDTSVETLNSTQQGTGAVQMRIKNANSHHDRLSQSKSMILTDVGKVTEPVNSFSTAAASFFCRSWSCLCAPSVR +TWYLFCEAAAEETQVIAMTDEKPKEGVKTETNDHINLKVAGQDGSVVQFKIERYTPLSKLMKAYCEQQGLWMRQIRFRFD +GQLINETDTPAELEMEDEDTIDVFQQQTGGVY +>A0A667IYE1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:61383 +MADKKPKEGVKTRSNDHINLKVAGQDDSVVQFKIKRHTPLSKLMKAYCERQGLNCVCAQAYCIFLTNWPIVCFY +>A0A3Q1GDS8|unreviewed|Ubiquitin-like domain-containing protein|taxID:80966 +MTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKELGMEDEDVIEVYQEQTGGLWND +>X8J089|unreviewed|Ubiquitin-like domain-containing protein|taxID:1086054 +MSDGQPEGSANPQAQSDNDPISIKVVTSTGEEVYFKIKRGTKLKKLQGAYAAKVGKDVSTFRFLYDGNRINDDDTPSSLD +MENDDTIDVMVEQVGGAI +>A0A395NEJ6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:490622 +MSENDNQQSPTGQEPPPNSEHLNIKVTDNNNEVFFKIKRSTKLEKLMTAFCERQGKSLNSVRFLFDGTRVQPTDTPDACT +KNKSEGACGDDAMAMKGRDDDNKLERRDTEDRRRREVCV +>A0A2I4DY72|unreviewed|Small ubiquitin-related modifier|taxID:51240 +MSGVTNQEEDKKPTDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVELNSIAFLFDGRRLRAEQTPDELEM +EDGDEIDAMLHQTGGAVA +>A0A0B6Z7Z3|unreviewed|Small ubiquitin-related modifier|taxID:1028688 +MEDQQSQKKEDHKESEHINLKVTGQDGSVVHFKIKKNTPLRKLMGAYCNRAGIQTGVVRFRFDGNPINDEDTPAMLEMED +GDS +>A0A0L1J2L6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1509407 +MRSFFKRPSWATRGDDDLDSEFYRRAGQTYADIIAASKVARDSPLGSPGSSTTEDGKVCKRRHISGEPLSREPAPRVLPD +DGQERSDIQGVSLRSVDSWKTSPYISDCNDYWTPVQLPTDKASALGSKVDSSNTRDIRQTHVWPYPSTNTEITETENAVD +EIPAPCDARKNQRKVAVHTDQHHDSMEYDTVVQILITSKIESTKPLIIHRKMSQSLRDVRLAWCNRQSIPKEMQSSILLT +WKGRRLFDVTTCRSLGIGVPQGLADSAVHGDHIQHGSKEDIRIHMEAVIEDNVMAINDWQASHESYPAYAQESTATDGSR +LLSTRVVLKCPSAGDLELKVSSRMQVSRLVTTFRDEKNLPKNREVYLVFDGDRLDPSSCLSMYDMADGDLVDVVIK +>A0A481YQY8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2506601 +MILWIDKKMKRTVIIMRDNRKVYFSINENSKIKKMMMVYCQRLGLYRNKMSFYLNDKYLYPNDIIGELSKQNTIYINAKY +EINQYYIDLENKCKEMYDTMIELGRKLQNPEQRTSFLDNIDYSINKIYSMNF +>A0A8B8GDG1|unreviewed|Small ubiquitin-related modifier|taxID:143950 +MLLISNRPKDTRVVPEHINLKVLGQDNGAAHFKIKIYTPLKKLMNAYCERTGLAMATVRFRFDGQAISEADTPSSLEMEE +GDTIEVYQQQTGGCFNYTYY +>A0A9J8BPC9|unreviewed|Small ubiquitin-related modifier|taxID:630221 +MKKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTID +VFQQQTGGAC +>L1J7A4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:905079 +KEGAVATENITISVKLEKCRDVSFKVKPSTAMQKLMDSYCLKQHLRIEKVRFEY +>A0A178VW71|unreviewed|Small ubiquitin-related modifier|taxID:3702 +MVSSTDTISASFVSKKSRSPETSPHMKVTLKVKNQQGAEDLYKIGTHAHLKKLMSAYCTKRNLDYSSVRFVYNGREIKAR +QTPAQLHMEEEDEICMVMELGGGGPYTP +>A0A820NRQ2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:433720 +MTAENKTDEYIKLRVVGQDNSEVHFKVKMSTSMGKLKKSYAERQGVGVATLR +>A0A7L2DMT1|unreviewed|Small ubiquitin-related modifier|taxID:159581 +GVKTENEPIDLKVAGQDGSVVQFRIKRRTPLGKLMKAYCCRKGLSLRRVTFLFDGQPVKGDDTPAQLEMEHKDTIEVYQQ +QTGGGC +>A0A9P6P474|unreviewed|Ubiquitin-like domain-containing protein|taxID:2184029 +MEGEKVEKKENASSSEHINLKVVGNDNNEVFFKIKRSTQLKKLMDAYCERQGKSTNSVRFLYDGHRVMPHNTPQELDMED +GDSIDVMVEQIGGTSSC +>A0A8S0VIS4|unreviewed|Small ubiquitin-related modifier|taxID:158383 +MSTPGQEEDKKPGDPSVHINLKVKGQDGNEVLFRIKRSTQLKKLMNAYCERQSVDFNSIAFLFDGRRLRAEQTPDELEME +DGDEIDAMLHQTGGAAAALLG +>A0A367JED9|unreviewed|Ubiquitin-like domain-containing protein|taxID:86630 +MSEEKQEKKENASNEHINLKVVGNDNNEVFFKIKRTTQLRKLMDAYCERQGKAPGSVRFLYDGTRILNHNTPNELDMDDG +DSIDVMVEQIGGC +>A5DMB3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:294746 +MGESGPRKRKDDPFDDFFALSAPSGKKHKKKRPREKKVENHEDEKRNENSPETINIDVDVETSPPAPNTSSPGPSRENSD +SHNQKMDNRDEKPLNDITVVDDAVDDIAVQDIVDEEDELLEFLKETSASLGHHKSDTYDFSDSNERRRSYVVRVISKLEP +ENAVTVDIGTKGLKKFDKIHEAALRELRKKPGSPMKQHNVHTTCLAWIEGRQEIKPFFKPSTLRIKPPLEFIGQNPAKIP +LTHITCLLYPKSHSYLDYPEFESTSSWKKLSQLSSDLSAMDELSVLSANSESSDEDPLGDSNPVANPVANTPRDTPDSQP +DADYFEIGLKGKDNKRISVQVCSTTKLRDLLAHYLKAKEIDVSAASRAKLLFDDEELDLNGVVGDTELEDEYEVQVVV +>A0AAD8KMQ7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:13708 +MTEPPEELEPLFDYTRVQPLDVVCLDEDDDDDCCAVVPSKRRKHAGSVAEKVQVTREEVVIDDGEDNDDLDWLKSPPKVP +VNKEKLCENSIIKELRLKREELLSFTESTKDMVRTVEECVKRDLKTLADSDCESPIEKPSKPAVDRPKIVISIQDKDGLK +QFRIYKDDKFEKLFKMYADKVKNKVENLVFCFDGDKIGPSTTPSSLEMEDDDMIEVHVKSS +>A0A7J8R948|unreviewed|Small ubiquitin-related modifier|taxID:34287 +MSATGNVGGGGPEEDKKPADQANHINLKVKGQDGNEVFFRIKRSTQMRKLMNAYCDRQSVDLNSIAFLFDGRRLRGEQTP +DELEMEDGDEIDAMLHQTGGAE +>A0A8C3WWB2|unreviewed|NFATC2-interacting protein|taxID:51154 +MAEPVRKRGRRSRGGGVGRGARGSRGARGRRPQAQRSPTRRSLDPVLVDLVSDSDEDVLDVATARGAADPAEVPLPETPV +PAARRDDSNSDRDSEGADAGPAGAPPVLVRRRRRLLLDPGEAPAVPVYSEKVKSSLHLIPDHVSLLKFCPPETEEEAESV +DMADSSSPHTEESPRPASLWKKKLRSKDSEEKEKVLLVQDTSPVSPPPPRTKSRKHSRALQKLREVNKRLQDLRSCLSPK +QPQGQDHPSQEDEVVLVEGPTLPEHPRLLPLKIRCRADLVRLHVRMSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPA +ATPRTLKLGVADIIDCVVLASSPEAAGTSQLIQLRVQGKEKHQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLSFFFDGT +KLSGKELPADLGMESGDLIEVWG +>A0A7K8BN40|unreviewed|Small ubiquitin-related modifier|taxID:156170 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A453FY34|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:200361 +VTITPVKPEAGAKGNIAYIHIKVTSQTAPDVFFRTKRDVFLQRIMDMYCGKHSPNRKAVVFLDEDGKKIRASQTAEEAGL +DDGHSISVNIA +>A0A2I4GGK3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:51240 +MADSTEELEPLFDYSRVQLLNFVCLDDDDDANASQALSSKRRKISEPIVVEDVEENPKVIHIVDSDKKEELDWLTPPPKV +STDIQKMIQEDPTIMNLRLKKQELVSFAQSAEDVLRAVEESAKRELGNSIQSSLKTVADQSSKPFGKRVKIVISIQDKNG +LKQFRMYMDDHFERLFKMYADKVKLDIQSLVFCFDGNKISPAETPDGLGMEDNDIIEVHVKPS +>A0A9W8CV25|unreviewed|Ubiquitin-like domain-containing protein|taxID:147472 +MDPIDQTSNAGGADANKNNNNSNGANQADVKDKKPDTGNEHINLKVVSADSSEVMFKIKRSTKLAKLMQAYCSRTGKAYG +TVRFLVDGERVGSDTTPNDLGLEDGDTIDAMTEQVGGSSN +>A0AAD5J933|unreviewed|Small ubiquitin-related modifier|taxID:4023 +MSDAAMDPPPNPPPPVVKIEQAEKNNNPSSSNHITLRVKDQNQNEVLFRIKKSVPLKMLMDGYCVKKRVELNSFAFLVDG +NNLRRDQTPEEAGLEDNDEIDVFDHQLGVCIAGCCYFCFMLFLMS +>A0A061ELM4|unreviewed|Ubiquitin-like domain-containing protein|taxID:3641 +MSRPSGQASNSADGQPESIKITVKGQDGSTVVYKIGRKIKLSKLLHSYCQRKQLDYRTVRFVHEGRHVPGQHTADKLKLE +DGAEIFCMFLQTGGGFHIMPKTT +>G3TP58|unreviewed|Small ubiquitin-related modifier|taxID:9785 +LFFQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSAV +>L8HT26|unreviewed|Small ubiquitin-related modifier|taxID:72004 +QEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDV +FQQQTGGVY +>A0A1S3G5J4|unreviewed|Small ubiquitin-related modifier|taxID:10020 +MADKKPKEGIKTVNKDHINLKMAGQDASVVQFKIKRHTPLSKPMKVYCERQGLSMRQIRFRFDGQPINEVDTPAQVEMED +GDTIDVFQQQTGGVY +>O57686|reviewed|Small ubiquitin-related modifier 1-A|taxID:8355 +MSDQEAKPSSEDLGDKKDGGDYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYRQRQGVPMNSLRFLFEGQRISDHQTPKE +LGMEEEDVIEVYQEQTGGHSTF +>A0A7N4PIL0|unreviewed|Small ubiquitin-related modifier|taxID:9305 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGIY +>A0A3P8T8B4|unreviewed|Small ubiquitin-related modifier|taxID:161767 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGHC +>A0A2S7Q0F3|unreviewed|Ubiquitin-like domain-containing protein|taxID:2070413 +MGDVVDGASALPEPAKKKGFSIFKKKAVAPQAPIAEPVDHIDAFSRGKQLFAARLREEELERAKKAEKRERKRTSQSREK +SETSPRPEKKSRKDVQPDNVELYSSDSNSSDEVKERHVRKYAISVVYDRTSRTSTISTPKSRKSPTKPLRDAQRSPTSLI +GRYNKDVHQKVKDTTLQEPEQKGYISVSDTESDSDHNTTSPVKQRARRRSSSSPIPIPTPVAVAIGTTNDDEEHFSDEEF +PELLAKARERKRLAELEQARAAAAFANKNHEPGRSAGDDVFQLGPAAPADPVVNIFITSRLQDSKPLMIKRKLSGRLREV +RLAWCARQSVDGEPWPEDVKDSIFLSWKGKKLFDVTTCSSLGIKVGPEGDLHGTGEGFTDDGGIHMEAWTQGLWDDCLAL +AEIEGEASEVEEVEEVETEPVRIKLTLKANVKDLKDYKIAVKPTTTIQKLTDLYRNQKNIPGDKRVILDFDGEHLDPEMT +VVEAELSDMDTIDVYIR +>W7U9I0|unreviewed|Ubiquitin-like domain-containing protein|taxID:72520 +MKKTNPLYHSSSSTLANQARTMATVKTDTTATEPKSESITLRVKDQTGEETMFKVKKTTKMEKVFASYAGRKGVNVDSLR +FLLDGQRIEKHQTSAELELEDEDQIDVMLEQLGGC +>A0AAD8IB29|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:360622 +MEKMYESSTSQVVKLGKRPASSSATLEKRSKKRATEGEEETHGIIQLKVKSQEKEVIFNVKRSTKMEKILRMFCEKARVE +YRTMNFFIDGHSFPVNKTADELHLSNGDEIEAHGWQTGA +>A0A8C8S8B9|unreviewed|NFATC2-interacting protein|taxID:367368 +MAEQAAESRGQLQPQGTSEVQVWGVPKVILEEAQARTQESCPPDAGSPISGGDGPAIPPIYVGGSSSDSNGERISPLLGA +AGKPRPKRRRLLCSTEIPTVPVYSNKVTSSFKLCPMELSQKMPTLQCQGEADVDVDDISPIVPPRPERPHAPRLPQGPCA +DWLEEELQQEEAVRTEMEQRLQGLSSCLSAAQRSLREELAEDDVILVEPPLPPTPRQLQLKVRSRAEIHRVPVETLQPLQ +AVVDYMAGRLRVRPRQILLLLRDVELPPDSTPQALGLGVADIIDCVVDVAAGEQQDGGEPEAQLGPGELRLTVRGQEKDS +QLTLNVPRAEPLHWLMEHYKEAMGLGGRKLRFFFDGQRLAGTRTPEQLGMESDDVIEAWT +>A0A836IB39|unreviewed|Ubiquitin-like domain-containing protein|taxID:2802991 +MRRSLALLLHSTSACLLSARKLSQYEQEAYESHRRFTESRTYPGPIRAATPGDTRFYMGSVETILQENERHYWRAVVDDP +QVQYLLPLRIRFKTFIWVTSGWEQRMQVVQVMVQRDATVAELLQQVRIENQSPYLCTSSFKLSIDGKELDEQKTLADYGI +DEYSRIDAIEEKDHLLHTEAERPKDWNVDEMTEELLLRSPYKEMGMRPQRNLAPRYEAKPKGYHGKNDYSGMKQSS +>A0A0N4ZVE1|unreviewed|Small ubiquitin-related modifier|taxID:131310 +MSDNERAQENDTVNNSASMAADNDDEFIRLRVMGQASNEVHFKVKKTTTMQKLKKTYADRMGVSPQSLRFLFDGKRIENS +DTPKSLEMDQDDVIEVYTEQVGGTF +>A0A8I5TS81|unreviewed|Small ubiquitin-related modifier|taxID:9601 +MADEKPKKGVKSENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCEQQGLSMRRIRFRFDREPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A4D6NCC9|unreviewed|Ubiquitin-like domain-containing protein|taxID:3917 +MNAYCDRQSVDFSSIAFLFDGRRLRAEQTPDELEMEDGDEIDAMLHQTGGGYKFL +>A0A1Y3MZ10|unreviewed|Ubiquitin-like domain-containing protein|taxID:73868 +MELTIQNELQNNSFINDVVVDDDDDSNDRNINIIVQDKNKKEVKILINKNETIRHLGLMYLEKSSLDKSLISKLSFFFDG +QKLKNNQTIKEIDIENQDIIDLKIIN +>A0A822AHN4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:111125 +CSCAPSVRTGCLFCEVAAEATPALAKADKKPTGGVKTEENSHINSKVVGRDGSAVRFRRHTQLSKPMKAFCEQQGLSMRQ +SSFRFDGQPINETDTPAQLEMEDDGTIDMFQQQRGEVY +>A0A2G2HAN7|unreviewed|Ubiquitin-like domain-containing protein|taxID:1925666 +MRERIGRCMEEIAVCVPSAGALGMLLAMLVPPCFPIASVIGQIQDTSYSSLMADQGEVKAEVPQVSLKVVNADGAEMYFK +IKRGTQLKKLMDAYCKKQGISRSSVRFLFDGSPIDENKTPDDIGMEDDDVIDAMVEQTGGCVAW +>W4G5N5|unreviewed|Ubiquitin-like domain-containing protein|taxID:112090 +MSLYLRVKRRNQTFFILAEPHDTFLKVKETLASILTLSSPNQVQLWHTNKQKELLDAATVADQEIENDAVVYLCLKKENT +EVWEDIQVAKLELDHDSNNNDHSTKE +>A0A836IU73|unreviewed|Ubiquitin-like domain-containing protein|taxID:2803181 +MRRSLTLLLRSTSACLLSARKLSQYEQEAYESHRRFTESRTYPGPIRAATPGDTRFYMGSVETILQENERHYWRAVVDDP +QVQYLVPLRIRFKTFIWVTSGWEQRMQVVQVMVQRDATVAELLQQVRIENQSPYLCTSSFKLSIDGKELDEQKTLVDYGI +DEYSRIDAIEEKDHLLHTEAERPKDWNVDEMTEELLLRSPYKEMGMQPQRNLAPRYEAKPKGYHGKNDYSGMKQSS +>A0AA38ZYM0|unreviewed|Small ubiquitin-related modifier|taxID:103349 +MSATGGVAGAGTGGQEEDKKPMDQGAHINLKVKGQDGNEVFFRIKRSTQLRKLMSAYCDRQSVELNSIAFLFDGRRLRGE +QTPDELEMEDGDEIDAMLHQTGGVAWMCLTAN +>A0A8D1NA40|unreviewed|NFATC2-interacting protein|taxID:9823 +MAEPLRKRGRRSRGGGVGRGTRGSRGGRGRRPQSQRSPARRTLDPELVDLVSDSDEDVLEVATARGAADPAEVPLPETPV +PAAPRDDSDSDSEGADAGPAGAPPILIRRRRRLLLDPGEAPAVPVYSEKVKSSLHLIPDHVSLLKFCPPETEEEAESVDV +ADASSPHAEDSPCPASPWKRKLRSMDGEEKKKVLLVQDASPVTPPPPRTKSRKHSRALQKLREVNKRLQDLRSCLSPKQP +QGQDYLSQEDEVVLVEGPPLPENPRLLPLKIRCRADLVRLPVRMSEPLQSVVDHMATRLGVSPSRILLLFGETELSPTAT +PRTLKLGVADIIDCVVLASSPEAAGTSQLIQLRVQGKEKHQMLEVSLPRDSPLKTLMSRYEEAMGLSGCKLTFFFDGTKL +SGKELPADLGMESGDLIEVWG +>A0A8J1VPM5|unreviewed|Ubiquitin-like domain-containing protein|taxID:2778382 +MSDAGSPPANPPPEEAKPKPEDNTLNIKITSTDGNEVFFKIKRTTKLNKLKAAYADRVGADAASIRILDDQTANDLDLED +GDSIEVLLEQVGGA +>A0A8X7WEL0|unreviewed|Small ubiquitin-related modifier|taxID:52824 +MVSSSTTISVSCASKKSRSPTPQKKITVKVKTQQGGEEDVYKIGYGTHLSKLMEAYCTKRNLEEGTVRFIFGNKQLKPRS +TPTQLKMEEGDVIDIVTDQDGA +>A0A671VE01|unreviewed|Small ubiquitin-related modifier|taxID:8175 +LQDDKYKGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTLRQIRFRFDGQPINETDTPSQLEMEDE +DTIDVFQQQTGGSSL +>A0A7S7LHU6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:5807 +MEERNIEENNEDDDLFGEDIAFSQESVNRRLGKVQKRNRLAKKVCINKESQQNETREKISSNDNNHIEEDSDYEEFRPAV +RKKISRKEDTVLTIEKTQKKVGTKNEQVSQVITIEDEEREKSVIKLNVKVYKRKESDIIVIKTLVVALYRNDLVKKLVTY +ISKNLNPKPEKYLEDIKVYFDGDCVNMEMEIKEIGIEDEEQLEVKVPFECNWIK +>A0A9L0JZV7|unreviewed|NFATC2-interacting protein|taxID:9793 +MAEPVRKRGRGSRGGSRRARGSCGGRDRRPRAQRSPARRTLDSVLVDLVSDSDEDVLEVATASSAADPVESPLSEPPVPA +APRDDSDSDSEGAGAQPAGAPRAPVRRRRRLLLDPGEAPVVPVYSGKVKSSLHLIPDHLLKLCPPGAEEEADMADSSSSH +AEDPPFPDSPWKKKLRNKNEEEKKKKELLAQDTSPLPPPLPRTKSRKHTQALQKLREVNKRLQDLRSCLSPKQCQGQDHL +SQEDEVVLVEGPILPESPRLLPLKIRCRADLVRLPVRMSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPTATPRTLKL +GVADIIDCVVLASSPEAAETSQMLQLRVQGKEKHQMLEVSLSRDSPLRTLMSRYEEAMGLSGHKLSFFFDGTKLSGKELP +ADLGMESGDLIEVWG +>A7AQD2|unreviewed|Ubiquitin-like domain-containing protein|taxID:5865 +MATTSETPNSEHIQIKVRSPDGSEVYFKIKKKAKLEKLMSTYCVRLGQSPDAVRFLFDGDRIKGDSTPEELGIEHGDIID +AMVQQTGGAS +>A0A8C6DLT1|unreviewed|Small ubiquitin-related modifier|taxID:68415 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A7N8WJK4|unreviewed|Small ubiquitin-related modifier|taxID:205130 +MSKGIKSTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGLN +>A0A8H6AMY1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1964551 +MSDNEGSPAGERPEAPVSEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCERQGKAPNSVRFLFDGSRVQATDSPDKVWI +CKMVTLLKSIKSKLVANKSSLAFSSIPLHDDTIP +>A0A811P078|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:422564 +MTTAGEVDSAAGGEDLEPLFDYKRVQPRITFSFDDSDLEAADIFKHCNKRPKVHATTEEKESKPDEEAAAPKVVVLDEED +WLQPPPPKAAFRAPAVEDSTFRELRLKKQEWAKFAESAQDILQKMDAITKEEVGPKEPPEQIILDEEFEPPVEKAREKIV +ISIQDKDGHQQMRVYKDEKFDKLLKVYAKKAKLNPSDLYFVFDGEKINPSSTPQDLDLEDEDMIENCLKPSRYTAAAHVG +LVGKSHLQKCQSTLVCGKLLAGIGVGGFGMGDLLLVVVQWCVQRAVGVCKAYDALTADVKFCKLQLAVSCDLRGDWVRQS +YQSVSARDESSWNKLKLLSLHFSWGNEIETDTDCRQPRTTMAPCIKQQPCHWLREGRKHEHVPCAACRSIDSTHTSTVRI +S +>A0A2K6ADV1|unreviewed|NFATC2-interacting protein|taxID:9568 +MAEPVGKRGRGRGGWGGRGRRPRAQRSPSRGTLDVVSVDLVSDSDEEIVEVTSARCAADEVEVAPSEPPGPVASRDDSDS +DSEGADARPAGPPREPVRRRRRLVLDPGEAPLVPVYSGKVKSSLCLIPDDLSLLKLYPPGEEEEVELADSSGLYHEGSPS +PGSPWKTKLRTKDKEEKKKTEILDLDNSPLSPPSPRTKSRKHTRALKKLSEVNKRLQDLRSCLSPKPPQGQEQQGQEDEV +VLVEGPTLPETPRLFPLKIRCRADLVRLPLRMSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADII +DCVVLASSPEATETSRQLQLRVQGKEKHQTLEVSLSRDSPLKTLMSHYEEAMGLSGRKLSFFFDGTKLSGRELPADLGME +SGDLIEVWG +>F6W9U2|unreviewed|NFATC2-interacting protein|taxID:7719 +MECLVMTYNDQAVCMDDTAKKLGLSVADTIDCLIVHKKVGTTQYNSRDYISINFQCKFQKVKKNYKTNKYTSLQETFEKY +AADIGHKLQELVFKFDGDVIPKTSLPLDLDLENDDTIDVMRKKIQTTKFAK +>A0A8B7YVN4|unreviewed|Small ubiquitin-related modifier|taxID:133434 +MSDQVGQENKPGTNEGENAKGATSTGTDSIKIKVRDEMGTEVLFKVKMSTQMRKIKEKYCEKASKNVSNIRFLFDGETIS +DDTTPKELQMEAEDIIEVVSSQTGGRHTPRY +>A0A814FI39|unreviewed|RING-type domain-containing protein|taxID:433720 +MANLYQIENLLRCSICLNRFQIPKVLECQHTFCYTCLQNIYDSENQILICPICQRTIKLTEGTDELPDNILLINLMKIQP +IKGKCSSCQKIDTLTICEYCQCTKCTDCNEKHVNDMRKLLEIKLNELEKTNQNEFKVPIHNYFKIKRNEINNQFQLIRQE +HHSNLFQKQMHILEQLELKEQILLTQIENDFQLLEQIKLDIINRNIDINSKTESELLNVLIKASDIQKCLTEKLTQYYLY +SCEIILQXIYDSENQILICPICQRTIKLTEGTDELPDNILLINLMKIQPIKGKCSSCQKIDTLTICEYCQCTKCIDCNEK +HVNDMRKLLEIKLNELEKTNQNEFKVPVHNYVKIKRNEINNQFQLIRQEHHSNLFQKQMHILEQLESQEQILLTQIENDF +QLLEQIKLDIINRNIDINSKTESELLNVLRKASDIQKCLTEKLTQYHLYSCEIILQYDEDQTNAINHLCDSLQLNISDRN +SVSSEFINITLRTFLNQEYQYRISLDKTIYELKEIFSKQVNLDPKKILLTKFDNYTDELEDNRTLKSYEFNSTSILMVCL +RK +>A0A4T0FH75|unreviewed|Ubiquitin-like domain-containing protein|taxID:1540922 +MRLAPSLLLCGHLCVPDQFGPRTKGPDEECEDYELLLAPDNVPAQFFRSSSIFQSGRHPLTECEEAPSTLTTMAENENSA +NENKVNLRVAYSQGGSEDEIQFSVKPTTKLGKIFAAFCSRTGQDPSAIRFTYAGDRLDENSTVKQYEMEEDDLIHAHVSQ +VGGL +>G4N4P5|unreviewed|Ubiquitin-like domain-containing protein|taxID:242507 +MDDHDAPVASTATKPKRPLFKKRKVKSASNAPDTTASGEQGVGISTNVNLDEEEDDGLNLFKRSKDFFPVFVKDREEELA +AETRKSEESSDRKRRKVSPSADRASPKSDLYDVSEDEKERIRIRRDERPLTPPPTKDKSLLNSSGRRSGQRGVGKGKVNA +SPASATPSRRAAARPAPSSSIVIFDSEDEYVPRPTASRRSPVETKEPIGSPTPTKQQANNAKPIEIDDDLEEVAPATESL +DDEDNEFAHFVVAARERRENQKAVRAAAESVRGTKPVDERIIQVFVTSRLPPPKMKPVVLNTVMRKPIKVLRDTVVAFSA +SRGRPLTEEEQKGAFLVWKDSRLYSSSTLMSLGVVPDAHGGFSKTGSGNANDGVTVDGQLHFELFTEEIYAEWMQQLEKQ +RQKDLYQTISDDEGETGQKPAADGQDEAQGQDGKSSEKIRIFLKAKNLDQVKASAKADTEISELVAAFRNVRKIPADKQV +VIMFDGDKLAETDTVGDAGIEDKDVVDVLIK +>A0A485LIK3|unreviewed|Ubiquitin-like domain-containing protein|taxID:120398 +MSVYLRVKRKNQTFFVLAEPHDTFLKVKETLASILTLSSSNQVQLWHTNKQKELLDAATVADQEIENDAVIYLCLKKENT +EVWEDIQVAKLELDHHDGSNNNDHSTKD +>A0A9P8UXY7|unreviewed|Ubiquitin-like domain-containing protein|taxID:152316 +MSGENESGSPAGERSEAPAGAEHLNIKVTDNNNEVFFKIKRSTKLEKLMNAFCERQGKSMTSVRFLFEGQRVQPTDTPDS +LEMADGDSLEVHQEQVGGFCHI +>A0A512UKS7|unreviewed|Ubiquitin-like domain-containing protein|taxID:2562755 +MAQEAKEEGSDTHINLKVSDGSGEIFFKIKRTTPMKRLMDAFCKRQGRSLDSIRFLVDGTRIHPDSTPDSMDLEDGDVIE +AHREQTGGFL +>N4UML7|unreviewed|Uncharacterized protein|taxID:1213857 +MADAAKPKRRLPFKPTALRQKSDPKPAQKKGEDSEDEDGINLFRRAATFFSVAEKEAEEERRRRRAERERSSRAVSEVEE +RPSPSKNSEEPMKKRNHHEDDGARDFGSPPPSKRSRTSDDSPDAKVKPSPTNRTSSETPTKRMSRAAASRTPRKQEPPQS +KPIIFIDDSDDDVDEDDIYDASPIRKPVQTTDREPSPLVINADEDDDPFAEPDESDPPAASAEDDELEEYYVRLAEERKK +ARQQEEAEAQTVTVYVTSAIPETTNRQFRFTLSKPLKVLRTAWIQVHSGRNGTRADLADVFLTWRAHRLYDGTTLQSLDL +PGEYRKCGGDYGGFRDDEWTNVHMEMWTQQLWEEHERQVARQRRHDLGEFSEDEEGGVGGAGGGGADQDVAEAGPHEEKI +KVLLKTKTDEPLKTSVRPSTTIGTMKELFRKMRGLAADAPLTLMFDGDELQEDATVEEADIGDMETVEVYLR +>A0A8C9CND3|unreviewed|Small ubiquitin-related modifier|taxID:42100 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A8C0WB57|unreviewed|Ubiquitin-like domain-containing protein|taxID:51338 +IANKKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMTQIRFRFDWQPINETDTPAQLKMDE +DTIDVFQQQTGGVY +>A0A9P5R1R0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1896178 +MSDSDDSKPVQKKPQPRPRSKRSKVLPSSSSTPLTSPNSGLSSPRTDGGGTTRLADNYSERVEDDFFNRSSVSFHQIHRM +QETRLHEEMSKQDEELEILDLKAPNYHVLTILDLEEFDMLKEESKGAVQRKGQEQETKRKRELSLTPPPELPTRRLPTHA +PAPSKPANTMATAIDLDDDDDDYEKTNELDPDLASIAAKLNTIASRQSMEAASPLSPTSSLSQPLANRSPQQPSSPSNYH +TILLVIRMNRHPLLVIPPEYEEAMKLHERPVQVTVRSNNMFREMMTFYCKQKSINYASTIFTYNGVRLMPSSTPTALDFP +TRAIIEAYDQEAYKYIKEQENLERTQRLAEMERQAAETAAASQGDGAHGVGDSRQQDGDNDAEDDGSAEYIFIKLRGKDT +SDEKIRVKKTTTVNAIISHYKSIKRIPASTTVKLEFDDEALDSTTVIGDTEVEDDDMLVVRVG +>A0A444RQ14|unreviewed|Ubiquitin-like domain-containing protein|taxID:27337 +MIPWSSRLPLIKPIQAHRLISSPNHRPRYAEAVEHLNIKVTDNNNEVFFKIKKSTKLEKLMNAFCDRQGKAFNTVRFVFE +GQRVQPTDTPSALEMADGDTLEVYQEQVGGC +>A0A4Z1HN50|unreviewed|Ubiquitin-like domain-containing protein|taxID:54673 +MHSPTPDPQTPTSASRENKPEPGTGDGADTGKPKTVSVTVVDQQGDVITFKIKRAKPMLKIMEAYCQHKEIGDIRSVRFL +YDGLRIKKEHTADSLEMDVEARLDVFLEQLGGGHHKF +>A0A7S3M7V4|unreviewed|Ubiquitin-like domain-containing protein|taxID:89044 +AILPQACSPQPTRSRPLRKQEPLACSDMAEEAAAGHIQLKVKDQQGSEVQFKIKKSTPLRKLMDAYCSRLGLQASQVRFM +VDGERIAPDDTAEKLGLEDVDLIDVAMEQTGGR +>A0A194XKB5|unreviewed|Ubiquitin-like domain-containing protein|taxID:149040 +MSGSDDNGSPGAPEKPEGAGQSEHLNIKVTDNNNEVFFKIKRTTALKKLMDAFCERQGKAPTSVRFLFDGSRVQPTDSPD +TLDMQDGDTLEVHQEQIGGAN +>A0AAJ6ZJ50|unreviewed|Small ubiquitin-related modifier 3|taxID:66420 +MSDEKKGESEHINLKVLGQDNAIVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEV +YQQQTGGACF +>A0A5D2CN19|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:34276 +MKLNQADSTADDLEPLFDYRRVQPLNIVCLDDDCSDTSPVPSPKRRKFANPDVAEVDLDKDVEVIKVVNVEEEDWLAPPP +VVSTKAYSKIGEDSTIKELRRRKQELLSFAQSAKIMLQEVEESAKQEPSGSSKPSLDAVAKQPKNPAPERAKIVISIQNK +DEIKQFRIYMDDKFEKLFSLYANRAKLDLQSLVFSFDGDKINLAATPASLGMEDDDIIEVHEKKS +>A0A420Q9P8|unreviewed|Ubiquitin-like domain-containing protein|taxID:5507 +MKKLPFKPTALRKAAPKPKPTESEDSKDSDDDGLSLFRRSKEMAPIMAADQQRRWRRHREAEQEAERKRLEAIGEKRPRE +DSPDSDGLTNKDPGPKVSDGLPSLPGRAEGTPVTDQPLTQDGADRTSELVTPPSSKRSRLDSSSAQKPTLSSQLDIDEDP +FPDASPTRRLGPIRNPPTPSRNLKTEGFKPQAKPSTDPITIDSDSESDSEPPKPKTDLSSRPRSSSIELAERTLKPSKEP +SPPPVEEDEFAEYIRKAEEKRARQQALQANKSEEQSKEAFNIFITSTIPHTVPLQVRFSFNKPLRIVRDAWVKHQMNKGV +SIQADDVTLTWNNKKVYNTSTLIGLGIRPIGNGRAVSDSQGSAGFRENMTSMNVQAWNPELFQKMEQEQELQRKRDAGEL +SDEEEEKPAERIRFVIMLKGRDVEPLACKILPETTVETLISYFRQQRNVGSDKQVSLWWDGERLEEHVEMKDAEIEAQDT +IEVHID +>A0A4Y1R2B7|unreviewed|B box-type domain-containing protein|taxID:3755 +MMEEFSEELEPLFDYRRVQPLNVVYLDDDDFDAPSASPPKRRKISDSAVEKVDDTVKAVNVIDCGDKEEEDWLPPPPKVS +LDARLRGEDSTLRELRLKKQELASLAQSAENVMRAVEESVKKELSDSLKAVAEKPSKPRCERNKIVLSIQDKDGAKQFRI +YVDDKFERLFKMYADKAKLDLKSLVFCFDGDKIGPAATPDALGMEDNDIIEVHITERTAIGGSRRDFGSHGSYISRALRV +TRSLLFVSQSKGQLDNVDDDPVVQESHQEGSAEWGFQSFGGRSFCEVKKMKKLCEFCSVLRPVVYCKADAAHLCLSCDAK +VHSANTLFNRHLRTILCNSCKYRSAYVQCLDHKMFMCRVCDITLHIASQHQKRAISSYTGCPSAKDFAAFWGFELNELDS +SAHLDGILSTSCGSSCDSTAVNLDSCEQSCSQVEGFPAANSPTLAPGVDSEVGSSSQQYKILDLKRLQLTEGSSPSLLIR +GKEQSDLSSSVHHTSGRFDNNLDQSLQHSEITRFRQRGSLLQDLKVDNSPFPFSQLEHVPPSSTAGLPLDTESFWQCRSP +VESCQLWAQNMQDIGVCEELVCHDDFNMPDVDMTFQNFEELFGSDQDPTRALLDDKDVPYSSVLKYISLDKSDNGHARAR +MEHDASEVSSIFFNKVQNLEGSMDYCPCPIQPSSSTLSFCMSRFNAESSGTDCHESRLSPYIATGETSRNSPHDQEGGRF +ETRANAMTRYKEKKHSRLLVRKNRYPFRKGRADNVSGKKEEL +>A0A6B2EGE2|unreviewed|Small ubiquitin-related modifier|taxID:1109342 +MGDEKKDNKTGESEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPNTLEMEEGD +TIEVYQQQTGGSK +>A0A672T5U3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:75366 +MSDEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGTC +>A0A8H3AMS7|unreviewed|Ubiquitin-like domain-containing protein|taxID:456999 +MADATPSQDAKMMITITHSKGAAPDVKVAVKKVSQLRKVFVAAAERFRTTPDALVFKYNGQVLEGDHTPKMHEIPEGGVI +TAYPADEEDASTQDLQNTQVSMDRFGGDAMDQDEPSPSAKNDKITSKRYVVLIQKVAFQIKVARVKPLKAAFDKAHEQFK +KAPNTFRFFYNGTRLKDDDTPKMHEMENNDEIDANIQQVGGAFLA +>A0A1A8EIP0|unreviewed|Small ubiquitin-related modifier|taxID:1143690 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGVY +>A0A2H3DHW2|unreviewed|Ubiquitin-like domain-containing protein|taxID:47427 +MSQEPEDIKPKININIQTDDGTKITVLVRRDTKFSKVFQAAEKKFGKEPGTFKFTYEGKRIQKDETPAEVDMEDGDTIDA +HLGQVGGGHL +>A0A2K1JIF2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3218 +MANRAILSTVVNLEDDDDDDIKLPSKSGDALAPQPPGTISDSRSPSYVSDLEQDDTDDEFKPLFDYTETVPSPTYFSDDD +EDDFKFSSAPKRRCVRAQAKEPSTPSPQEEIVTVGDDDDDESWLLPSPPKSSPLKFPNRATSALLSANYALHQLRQSQTE +LMGLQFAASPEGIKRVEEQAKLQLQHRPDPESPLAANTSKDLNFHEEILESKSVTPEKREKVLLKVQNKTGSYQSIRIFM +TDKFEKLFSVYAEMVDAPLANLSFCFDGDQLSSCGTPKEHDMEDGDVIEVYSKI +>A0A3R7LHM4|unreviewed|Ubiquitin-like domain-containing protein|taxID:83891 +MEGNHANESNNNNNNGEAGEKPAVKTETPLVSIKVVNADGAEMFFKIKCGTQLKKLFDAYCKKQGISRSSVRFLFDGSPI +DESKTPQDLGMEDDDVIDAMVEQTGGNTLC +>A0A7J8I3Q4|unreviewed|Small ubiquitin-related modifier|taxID:27622 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDE +DTIDVFQQQTGGSRAAGCLLGCSL +>A0AAD7SKE1|unreviewed|Small ubiquitin-related modifier|taxID:143900 +MADEKPKEAVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGLF +>A0A2K5D1T8|unreviewed|Small ubiquitin-related modifier|taxID:37293 +TSDLSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0AAE1Z1G8|unreviewed|Ubiquitin-like domain-containing protein|taxID:300844 +MSTPVQEEDKKPGDQSGHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDEDGNE +VFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEMEDGDEIDAMLHQTGGAAV +>A0A3M7I574|unreviewed|Ubiquitin-like domain-containing protein|taxID:91943 +MASEPVEEMPYTEPPPAQQPATPAQPDQLTLKFRDMNDYSIDFKLKPSTKLVKAMNAFSARLQKDTKELRFLSEGRRVLP +DQTPSDLDLEDGDEIDVHMEQIGGYMI +>A0A150H0S7|unreviewed|Small ubiquitin-related modifier|taxID:33097 +MEEARGENDVKLKQEGNVINLVVKDQTGNEVHFKVKMKTRLEKVFNAYCNKKGVDPGSVRFLFDGTRVAAQSTPEDLGME +DGDVLDCVIEQVGGC +>A0A7L2GG32|unreviewed|Small ubiquitin-related modifier|taxID:48427 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A7L0G5K4|unreviewed|Small ubiquitin-related modifier|taxID:56343 +FFMQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A6A5SB92|unreviewed|Ubiquitin-like domain-containing protein|taxID:706981 +MSDTGSPSNVQQKPEDGGQSEHLNIKVTDNNNEVFFKIKRTTPLGKLMNAFCDRQGKNISSVRFLFEGTRVTATDNPDGL +EMQDGDTLEVHQEQIGGSC +>A0A8H3W174|unreviewed|Ubiquitin-like domain-containing protein|taxID:702518 +MSGEHENGSPAAGGQDAPPAVEHLNIKVTDNNNEVFFKIKRSTKLEKLMTAFCERQGKAISSVRFLFEGQRVQPTDTPDT +LEMADGDTLEVHQEQVGGSN +>A0A850XDM9|unreviewed|Small ubiquitin-related modifier|taxID:33601 +QEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEGDTPAQLEMEDEDTIDVF +QQQTGGVC +>A0A7L2NUE9|unreviewed|Small ubiquitin-related modifier|taxID:182897 +QEGAETENEHIELKIARQDGSVARFRIKRHTPLGKLMKAYCCRRGLSMRHIMFLFDGQPIKENDTPAQLEMEHEDMIEAY +KEQTGGRC +>A0A135LBP5|unreviewed|Ubiquitin-like domain-containing protein|taxID:5078 +MSDKEGAAPPTEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKQISTVRFLFDGTRVRPEDSPDTLDMADGDTLE +VHQEQIGGC +>A0A3B5B296|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:144197 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGHC +>A0A7L3UTA6|unreviewed|Small ubiquitin-related modifier|taxID:84834 +ILQFSVQEGVKTENEHIDLKVAGQDGSVVQFRIKRHTPLSKLMKAYCCRQGLSLKHIMFLFDGQPIKEADTPAQLEMEHD +DTIEVYQQQTGGGC +>A0A7K5DIP7|unreviewed|Small ubiquitin-related modifier|taxID:369605 +PQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTID +VFQQQTGGVY +>L8FW93|unreviewed|Ubiquitin-like domain-containing protein|taxID:658429 +MSTPDPSSPLRLPLRLPLRLPHQRRSSASARARSSTAATTTDAIGFFSRAKDVFAENVEVQRREREREREREREREREVQ +REMEVERVRELERARREKRERVVGGEVGGGEGGEEVDSENERRRKRSGSEDRSNTPAGESEYGDEEAPIEREGSTHPTYG +NSVASPGPSQRNTRSQAQIISLSSDDEDDKPAPSPRPTYPSAFSSPPPKPVSTNPEPIAIPSSPPANPPSDDDELYADLI +AAARRQPATTAAAPSNAPDPTLTILITSPLPNTTPLLIRRRLSQRLKDVRLAWCQRQPPHAGTAATSIFLTYRGLRVWDT +STCGSMGVKISRAGGVLDDGGGGEAGDVHLEAWTREAFEAYKAAEEAKARNAHLGLENDNNGISGGSATETAPSQQQPQE +EKLRIILRAKDMPEVKLRVKATTKIADLVAAFRAQREAEVGGRSVELWFDGDRMEEDDCVGDADLEDLSGVDVVVRL +>A0A8T0LBZ5|unreviewed|Ubiquitin-like domain-containing protein|taxID:3914 +MFDVIVVVRCMVARDLRLLLAFMVVCLVACSVASLTLLCGGCSLLCVTHVLLHASCESSMSGSGEIVQWMLEVDYTVGVG +GAKVGVILHPFPLCVQKNNMATTTIAGHKRKSPPDDVCTDVDLSISFQDGNKLFFKVKQNLEFFKVFRDFCNRKKLEYET +LKFIHEGTEVKGRQTPKMLNLENGAEIFAVRSQVGGGVSY +>A0AAD8FYU5|unreviewed|Small ubiquitin-related modifier|taxID:40147 +MADEKPKDVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGLY +>A0A094HC99|unreviewed|Ubiquitin-like domain-containing protein|taxID:1420914 +MSGSDENGSPGSAPSKPEEAQQTEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKAPSSVRFLFDGSRVQATDSP +DTLDMQDGDTLEVHQEQIGGCGSA +>K2HME3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1076696 +MSDAQHSPSKDIPKEPAKDPVKDEPTKTTEKPVNNEQINLKVVTQDSTEVFFKIKKNTPLKKLMEAFCNKQGLNMSSVRF +LSDGVRITPDKTASDLGLQDGDVIDAMMNQVGGF +>A0A8S0VUY3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1973307 +MADSTIARPRPRPRPVAKASSSTNVVPSATPATSGAGSSTNAITAPMGRVIVVEDTDEMFMRNRNRTAKTWQKLEQLNKE +VIKVKDDTTDSDDEEGSPRRKHKKQKREPSAVPQWQKNKNIARMLSQDLSESSDDEVEITGESSTPNGKRFGKRKRRSRS +RSITPPPALPQHQIQSAKDLVRKTLQAAARPSSPTVIDLDPDESTDTIILQPELNALAQEIAEQARRGSSQAPEVTSGDE +VVITVRWQPHPLDTNGKKEEWKYQMERTDNFRDLFEATAEDSGILSANLIMTYQRSRIFPSVTPQTLRIWADSAEFMAYE +KTAFDYIQRSNIHIRPQNIDSIPSTSNDTVEITSDSDSDVQELPAHSQLTQAVQSQQESESEAEEADQGEKFKLILRSGV +TSGKDITLVVRPTTKCGAIVKAFLKKAGMTEQYPEVFTDAVVPASAATAKGKKGGKKSKAAAATAILPPKDPRLCIDGDK +INNDMEIGDADLEDGDMVEVVGL +>A0A7J7EGA5|unreviewed|NFATC2-interacting protein|taxID:77932 +MAEPVRKRGRGSRGGGIGRGARGSRGGRGRRPRAQRSPARRTLDSVLVDLVSDSDEDILEVATAPSAADPVEVPLPELPV +PPAPRDDSDSDSEGADAQPAGAPRALVRRRRRLLLDPGEAPVVPVYSGKVQPEADMADSSSSHTEDPPFPDSPWKKKLRS +KNEEEKKKKELLAQDTSPLPPPLPRTKSRKHTQALQKLREVNKRLQDLRSCLSPKQHQGEDHLSQEDEVVLVXXXXLPES +PRLFQLKIRCRADLVRLPVRMSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIGERKAGTWSLE +EALPWGGAKGKGPEGALLPTPAQAWLPTLPPTDCVVLASSPEATETSQLLQLRVQGKEKHQMLEVSLSRDSPLKTLMSRY +EEAMGLSDRKLSFFFDGTKLSGKELPADLGMESGDLIEVWG +>A0A8B8WK43|unreviewed|Small ubiquitin-related modifier|taxID:9771 +MSDQAAKLSTEDLGDKKEGEYIKLKVTGQESSEIYFKVKMTTHLKKLKESHCQRQEVPMNSPRFLFEGQRIADNHTPKEL +GIEGEDVIEVYQEQTGGHSTV +>A0A061H149|unreviewed|Ubiquitin-like domain-containing protein|taxID:1277687 +MSDDEDDIDFYVRKPPPRKSRRRHSGSSVPSSASYSDDSDDSRSPYASDRSTAAKPTTAQTAKTSQTDNFDAPLASPTFS +ADAKLSAKARTTSPVKRRRSPSLTPPPEPPEMQLKAARQLVRQHLASFHAQTSFSSDEDEPAIRPDPSSQSPETTLVLDP +ELARYYRGKDAERVREHARQQEAERRERRRRQLSQRRSESVGAPNAPATGTAKAKGQESIAEESDGFEVVPGPSLASPPS +SGSKNGTGVGAESKGSTATSNGAEVITLSDSEPEPAAARGTHPAGPPSSSNDPSASAAAASKESNEPTLHLSLKSRTNHT +LNVTVRATTQIERIIAHFVETHASSLPSEARGKGAIKLVFEGQALSGDSTVEDCELEDDDMLHVVW +>A0A6J2TJW5|unreviewed|Small ubiquitin-related modifier|taxID:7225 +MSDEKKGGETEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIE +VYQQQTGGNAY +>A0A5K3F9V5|unreviewed|Small ubiquitin-related modifier|taxID:53468 +MGDSSTAKEKSNEPINVSVHGQDGSVIRFKIRRTTPFKKLINVYCQRMGLSVSNVRFTCDGEHVQYEDTPESLDINDNDT +IEVFHTQTGGF +>G7N8P0|unreviewed|Small ubiquitin-related modifier 1|taxID:9544 +QEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKETQWP +TPAILALWEAEAGWITAGQELRPAWATWRNPISTKNRKSSRLGMEEEDVIEVYQEQTGGHSTV +>A0A7K5GIW9|unreviewed|Small ubiquitin-related modifier|taxID:1352770 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A7L3LTL0|unreviewed|Small ubiquitin-related modifier|taxID:2529409 +LSLPPPLLQEVVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQQLEM +EDEDTIDVFQQQTGGVC +>A0A8E2ATL1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1052685 +MSAPPEEELVDVKPKVALVINHEGQQCTVKVKANTLLKKVFDAAESRFNVPPGTLRFTFEGQRIQGHQTPGELEMEDGDQ +IDAHLGQTGGGRS +>G1R5R3|unreviewed|Small ubiquitin-related modifier 1|taxID:61853 +MTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>D7G8L3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2880 +MKQKLADATNIDMAPTVMGRLRASGVATGSPVVSAETAARREREQNQKGVKLMVTRSKQQQHLFHTKLGTLVSVVEEKCR +EDPDLGLPGGGGGCGGRSFLEDDIFDQSLAEKQLESGKTLRESGIPPGRVDLRLDVKGGSGGGGDCASGAPITLKLRVEG +GKAFMVTTTTGTKFSAFMEAFNEKVGIPQERASECVFKFDGDKLNPDGTPEGEDMEPEEIIDAKFPADVMNSVQAAPTEL +SLAAPKKKKVPRKVPGKGKAAVRKTTAAALAAAAKPLGGGSGSRPTRGGGSGRVTRSRSGSGGGGEGKQPEVVVLD +>A0A8H5HGD3|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:117010 +MAESNRPRPRPRPKPKPKVKAAPSVEEITSGPSSSTHRASSPLKEVQVVDNDEMFMRNRGRSTKVWEKLEQMTKETKVVY +VDSDDDEDDATPKRRKAKRKAPSPWRGNSALNRLLSVELEDDDDDDGIEFVGTSATPRKTQDIARKRPRTRSRSITPPPE +LPRHQLQHARALVQKTLNTNPRPVSPNHRDDNHSDDEIFSHPELARLARSVSRAPSHASSPAPEGAGTVQLAVKWQPHPL +NKAGQEDVWVFKMNRDDNFRDLFEAVAEEASILSDNLIISYNGKRIYSSVTPMALQLWGEADLVACDKTTYDYLRANPVA +ASHTLSAFDAATPDPDSDADAPSPSQDAPAPDDAESDAEGDTFKLILRSTISAKDITLTVRPTTKCGAIVKAYLKKAGVA +EGGKKKDPRLCVDGDRMGNDVEIGEADLEDGDLVEVVGL +>A0A978URQ5|unreviewed|Small ubiquitin-related modifier|taxID:714518 +MSATGGGGGGGGGQEEDKKPMDQAAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVELNSIAFLFDGRRLRAEQ +TPDEVNFWVLEMEDGDEIDAMLHQTGGNA +>A0A3P9C5P7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:106582 +MADEKPKESVKTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQVIMALRHYTNTDHFLSGHRSL +>A0A8C2BXM7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:7962 +SEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGAC +>A0A3P8VX92|unreviewed|Ubiquitin-like domain-containing protein|taxID:244447 +VEWSKKEKNVFGQKVCFLVIVITVLKCIYFLGLDFYFLCTPNFNTRSISTNLCYLITSLLQEGVKTENNEHINLKVAGQD +GSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTGGLM +>A0A4Y7L9N6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:3469 +MVVVSNVIKVKEEKPIEEEPNSRIDIKVASYHGNGNRVGFRIKRNARMGKLMQAYCEALKIDITSIKFILDGKQIKQEHT +ADQVIFL +>A0A7S1VWN3|unreviewed|Ubiquitin-like domain-containing protein|taxID:267567 +EDRRVIKKSNYLTSDALRSLFFRQHSNMSDNEGQKPADGGEDQKPGAEPITIRVRDQTGEETFFKIKKSTKMSKVIQTYA +SRKGVDSTTLRFLVDGERVQPDDTPGSLDLDDQDQIDCMLEQSGGCL +>A0A0D0UKE6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1296109 +MSERGSNPPEEKPKAEEAAADPNTLNIKITNTNNEEVFFKIKRTTKLNKLKSAYADRVGTDVASIRLLFDGHRILDHQTA +NDLDLEDGDAIEVQLEQVGGY +>A0A7K4Z4E1|unreviewed|Small ubiquitin-related modifier|taxID:153643 +PQQEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGFY +>A0A6B2FCA8|unreviewed|Small ubiquitin-related modifier|taxID:88079 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGIC +>A0AA39J590|unreviewed|Ubiquitin-like domain-containing protein|taxID:1929756 +QIAASTGYEHIFKLKTTTSLRKLFYVYAETIGKEVDELKFIYEGQRLNPHNMPNTYEMENGGTLDTV +>A0AAA9SC21|unreviewed|Small ubiquitin-related modifier 1|taxID:9913 +MDSGPKHKAYLGAAVINSSVRPQLKPALNPPASGEPRRPQRVFPRRLSSFPSPSSLSVAEVTQGVAEVPPAAVLCCWVER +RICKPRSEVLPTRGRWCAETPGETTVTMSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQ +RQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>V8NK48|unreviewed|NFATC2-interacting protein|taxID:8665 +MAETVNTVSSDSESEGTPKKPFPKRRRFLTSSVSIPVYSTKVQNSLKLLKNSLKLPDKIKERCNKNLPFSSEDEDEEEKP +ISLKQLKNRPSRIFDQSFKNLSMSISAAKKSLQDQGFDEDDVVLVDAFEPRELMLKIRCRVDIYKICILMRVVDRMSQIL +KVHPNRIILLHYDSELSVDATPAKLDLGVADIIDCIVETSNQRANDPGALLLRVQGKDRGSVMEITIQKGEPLEALMNHY +KEAQGLGRSKVAFYFDGQRLTETLTPEQLGMESGDVIEVWY +>A0A7K9I6H8|unreviewed|Small ubiquitin-related modifier|taxID:135168 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>B5X6B4|unreviewed|Small ubiquitin-related modifier|taxID:8030 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGLY +>A0A2N0Q3H9|unreviewed|Ubiquitin-like domain-containing protein|taxID:588596 +MDQLSPQFIKTEAVDPIDSFISFHVKNVLRTTPFKKLKEVYCKRNRLKIHATKFLFDGLNVMDNDTPDSLEMEEGDSIHV +IFAPAIRNVITNSDQLLSQFIKTEEPTGSANSFFSIMIYYDYDYVKFICPKNQKNDSIKRKETTYIVERAKPLKKLMESH +SEINGLSPATLRFLFDGCRIHYDDTADFLERKTTILSIMCPRE +>A0A851JVK5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:237420 +LSPPHPAFSVQGGMKTENEHIDLRVAGQDGSLVHFRIKRHAPLSKLMNIYCSRQGLSMRDIIFLFDGQPVKETNTPAEV +>A0A261Y0W5|unreviewed|Ubiquitin-like domain-containing protein|taxID:1938954 +MSDSEKPVEKKEEGGQHINLKVVGSDHNEVFFKIKRTTQLKKLMDAYCERQGKATSSVRFLYDGQRIQPTNTPNDLEMED +GDSIDVMVEQIGGAIHM +>A0A9P3N626|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2790670 +MGIPYQPFQATSVSVSSRASRACASAFVSRGVAPQALTSPTGHHRDGQAPRSLPVAASNLATHVSVRLLSDGGDEQLFKM +RRSARLAFLLDLYCQQHRSARRASVQLWFHGRPVGELATPDDLRMVDSDSVRVVECN +>A0A0C3NDI0|unreviewed|Ubiquitin-like domain-containing protein|taxID:870435 +MAEDIPPTQSQAQSEVKPEGDNSPINVKVVSSTGDEVFFKIKRNTKLSKLQGAYANKVGKDVASIRFLYDGNRINEDDTP +ASLDMEDNDTIDVMVERTIFNILNHLSRSLTNICRGRRIKIACVSVSLLPIVVFLCF +>A0A7K6LB48|unreviewed|Small ubiquitin-related modifier|taxID:254539 +ILRFSFQEGVKAENEHIDLKVAGQDGSVVQFRIKRHTPLSKLMKAYCCRQGLSMRQIMFLFDGQPIKEADTPAQLEMEDK +DTIEVYQRQTGGGC +>A0A8U1FCG5|unreviewed|Small ubiquitin-related modifier|taxID:8040 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLTIRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGFFH +>A0A8J5UT70|unreviewed|Ubiquitin-like domain-containing protein|taxID:2053667 +MSDNQDSNEIHFRVKMTTQMGKLKKSYSDRVGVPMTSLRFLFDGKRINDDETPKQLEMENDDVIEVYQEQTGGRF +>A0A9X9PTQ1|unreviewed|NFATC2-interacting protein|taxID:48420 +MADSSSPHAEDALFPESPWKKKLRSKNAEEKTKEVFLVQDTSPLPSPLPRTKSRKHTRALQKLREVSKRLQDLRSCLSPK +QRQGQDHQNQEDEVVLVEGPTLPESPRLFPLKIRCRADVVRLPVRMSEPLQRVVDHMATRLGVSPSRILLLFGETELSPT +ATPRTLKLGVADIIDCVVLASSPETSEMSQLLQLRVQGKEKHQTLEVSLSPDSPLKNLMSRYEEAMGLSGHKLSFFFDGT +KLSGKELPADLGMESGDLIEVWG +>A0A0C3QTB9|unreviewed|Ubiquitin-like domain-containing protein|taxID:1051891 +MSDTEEVDKKPDVKPEKLTITVRASDGAVTKFMLKPTAKFEKVFAAFENAKGAAPGTYRFLSSEGVIIRSQETVGDYNWD +EDEEISAVLAQQGGAFIS +>A0A1B7N082|unreviewed|Ubiquitin-like domain-containing protein|taxID:1314800 +MSEDTEDVKPKLSLVINYEGTQITVKVKHNMPFKKIFDAAEKRFGKEPGTFKFTYDGKRLRAENTPVDLEMEEGDIIDAH +LEQTGGGKVMC +>A0A9Q0UG46|unreviewed|Ubiquitin-like domain-containing protein|taxID:40686 +MSGATGQPQEEDKKPNDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRGEQTPDEL +DMEDGDEIDAMLHQTGGAVKTTPTKSFDSNCTILLGLDLQCLVCWDMAHLSLPLLSLLTSPS +>A0A7R8W0M5|unreviewed|Uncharacterized protein|taxID:163714 +MPPQNQIPVYIKVRVIGLDSYEIHFRVKTSTLMGKVRTSYAARVGAPVSSLRLYFNGQWIDDDETPEQLNVKNNDVIHVR +QIKLPDARSLLLLMQMARYRENTGDRNAASDYIKLKVGLIGHDSSEIYYHLKMSTPMGRLKHFYAERLRTPVNSLRFLLD +GRRINDDETPEQLGMKNNDVIQVCQAKFPGARSLLLRLQMAGAEENTGDRNAAFDSITLKVVGQGFCEIHFRLKTSTQMG +KIKNSYAERVGAPVNSLRFLFDGRRINDDETPEQLGMKNYDVIQVNHQIKLTHALSKRRRHCLSGPQ +>A0A2G7G4M9|unreviewed|Ubiquitin-like domain-containing protein|taxID:656916 +MADAGLPTGDAPAPVEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCERQGKQSSTVRFLFDGTRVRPEDTPDTLEMADG +DTLEVHQEQIGG +>A0A835G6D9|unreviewed|Small ubiquitin-related modifier|taxID:7107 +MSDEKKGESEHINLKVLGQDNAIVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEV +YQQQTGGAPLV +>A0A2U4AB77|unreviewed|Small ubiquitin-related modifier|taxID:9739 +MSEEKPKEGVKTENGHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSGAASCLWGAAPRATVPSCHCARVRY +>A0A0N5ADR2|unreviewed|Ubiquitin-like domain-containing protein|taxID:451379 +MLRRVISCRQEFPARTGRCCVELSAARRCSMYSCGFLMKPLFLSPDAFTTKMADNSASGEAGDAPAPAPATNSEYIKLKV +VGQDSNEVHFRVKYGTSMGKLMKSYADRTGVAVNSLRFLFDGRRISNEDTPKTLEMEEDDVIEYVRFKHWYLNADLGVPG +TGRRALT +>A0A4U0V0B1|unreviewed|Ubiquitin-like domain-containing protein|taxID:329885 +MATSTAYQRATVEDADETPQLQTSTNGNGNGNGGGNGNNNNNVTVGADDPEPAPQPEPITIIFADVNGFELSFRLKQHTK +LGKAMEAFAKRTERDPGTLRFLFEGERLLAESTTESMGMEDGDRVEVHHEQIGGGGGAELPPSESIILTFADGQGYELFF +KIKRSAELGKPMVLFAQRIDRELETLLFFFKDEPVLPHATVESMGMADHDRIEVLYPEVERGVDGTRAEGAHREGKVEHQ +LETFASLTFADDNGCELTFKLKRNVELGRAMDTFAVWAGKDRDALRFLSYGSRLRDDATMENVSFICDTSFYTFMRMDVI +HEQIGGTTEVEMAQAEQLLSTLQL +>A0A6A3AA33|unreviewed|Small ubiquitin-related modifier|taxID:106335 +MSEPQEEDKKPGDQSAAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEME +DGDEIDAMLHQTGGTNDLTMFSFV +>A0A3L6TAL9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:4540 +MVSPCPKQEESVAAARVVVHQGGERRVVAVAAVIKPVMLVTLKVQDTHRRVVKRTMRRTDKLQGLMDYYYDVVLCTADAG +ARGAGRFIFDGKRVKGEHTPEDLNMVSGDKIDFFQDLLAGAGEEGPSRAGGVVDEEAREITRTMRATDKLQELMDFYYDM +VPVVPAGKGVFLYRGKRIEGERTPADYKMKDAQIDFYSEMKPNIFVLLAVTDIVDFVLRS +>A0A819IHP0|unreviewed|Ubiquitin-like domain-containing protein|taxID:2762511 +TTTSMGKLKKSYAERQGVAVGSLRFLFDGKRINDDETPKLLEMEDNDTIDVYQEQVGGSC +>A0A6A2XRG3|unreviewed|Small ubiquitin-related modifier|taxID:106335 +MSGVTNQEEDRKPADQTAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELEM +EDGDEIDAMLHQTGGAMA +>A0A6D2XTP1|unreviewed|Small ubiquitin-related modifier|taxID:9601 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>I3SU86|unreviewed|Small ubiquitin-related modifier|taxID:3880 +MSSGAAAPNTEEDKKPEAGGAHINLKVKGQDGNEVFFRIKRNTQLKKLMNAYCDRQSVDFNAIAFLFDGRRLRAEQTPDE +LEMEDGDEIDAMLHQTGGSVV +>A0A545UWM9|unreviewed|Ubiquitin-like domain-containing protein|taxID:43265 +MVRLGYSGPNSPYPGGIPNASARHINPPPLSLGESAAAPPNAANQASPRRQRRRDRGALDEHINKRLRRHVWASADRQWT +RKALDTERAAYFDTRVTARPEIWQTLHNALQVMWEPPTQDTNDNGQTALQTAQSMLTAAEISLPTGNLVNGAYDTFGNYY +ALPEWVVSDPQNMVEHDHNKDGSGSGDDDTQGGGEDGDVRREEKGKDIDGGEQVEICARLSETGNDIVISVSKTEIVRNI +IKRIAAEANLSSARKIRLAYMGKMLKETATLQSQGWQNGHILNALVFNR +>G4TRF1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1109443 +MPPKFKRPTIPTAAKAENKTSELDDDTFFSRNTKGWDGVDLKALTSPTREKRRSSSPEHEYISLPKKRKIKAKKAPDWMD +PDAVITLDDSDEAVEHFINDSEESKPRAQAKQDKGKGRAPRPRKRSITPPPEVSATKLIAAYQAANKLFENMEPSNITSN +SHRDEDKDEDEEPIEALDEETLAIIDKAKQLASIKSPELEAQSPVYAGGSSFHPDEEELETDSLKLYVFWKGPPREDFPQ +KWRFQFNLTAPFRRLNEMMQQKTQLPEEDIVLVYASKRILLGATPRSLRMRKDTTEMIDVWPRHEWEEANSATKLQPVVA +NSVDEDDDDIVEIMPPTLPTAPQAQPSSHEPADKIVLNMRCKKYPTPVSIEAKRTATSSRLLARYLTTVGEDPAEFDIEG +IARSRKPRLRLSFDGEELQPDDQIGSTDAEDEDVWDVIGL +>A0A7L4ENS4|unreviewed|Small ubiquitin-related modifier|taxID:43150 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0A4Q4X005|unreviewed|Ubiquitin-like domain-containing protein|taxID:1081914 +MEDPQPPSTQPKRKLLFKRTIPRKLAEKPKDDNDDGLALFSRSKEFFPDVIKDQQREAAEKAEKERRKKLERARKEKEEA +LKLQHQFHRGKDEEDDETASAKKRHRIYLSDDESDDVFTTRPQKSRKSSSASPKSPSTKRDSLSRHHTRTLRSTRGSRAS +RSTDPNTAVISLDSSDEDMKHATSLNKRSPSVRKPSPAKPQDSLEESDLELESGPQAGGDGNADFDCYIQGALERAEKRK +RERLEREAAEGAGGKDTGGPEPVVQILISSALDGIEPIAFKRKLFQPLAVVHRTWVQMQLNKQAPVPLAVLQGMFFTWRG +DKVYGSATLAALGIQPSPTDGSLYPAWERDPPAGYLGRDKVLFEAWTPELYEEFLRDRELERMRARGEWLPEDHPDGEAG +GDGKGSEEPDQEETKIRLSLKARDMDPENVKVRPSTTISMLSIVFKRLKRLPADKDVELRWDGEVLDPNTTVEDADIEDM +DSIEVYVK +>A0A1A8QY52|unreviewed|NFATC2-interacting protein|taxID:704102 +MADEESDRNVQPVQPPKRRRVLDPSAVIPVSVYSSKVSSCLQLKPTALFTDKENPDDVDESLWSGFFSRTSAGLSDSEDE +ADPHPSSENRVEDPSPHPPPPESPVRKQSRKATKNINEINKRLRAVSSIMSPEPLRRPSKRCKASSSVQPDLDHENKDDD +VIIMSPDTSDSVREIPLKVRCRADVYKIPVLSSTPLTDVVSQLSVILKVPPTSLLLLRHDIELPSDSSVGELGLSIADII +ECVVMRAEDQSSSSSSVTVRLQCKDKDSSQEYSIHRDTPLDTIFSQYLSSLPSTTRRKVRFHFDGSKVISGQTPAQLDME +DGDIIEVWI +>A0A852H6U4|unreviewed|Ubiquitin-like domain-containing protein|taxID:243888 +QEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQVNNRSKIKELY +LKFAAGVN +>A0A094G777|unreviewed|Ubiquitin-like domain-containing protein|taxID:1420911 +MSTPDPADPFASPTSAAPAPAPAPAAVTARKSLFKNRNRGGAAAATTTDAIGFFSRSKDVFAETVEVQRREREREKERER +EMELQREMEKERLKEVERARREKRARVVGKVESGGEDEGLDSENERRRKRSRSGERSDTESEYGYEESSRSVHREGSTHS +PYGNSIASPGPSQRNTRSQAHIISLSSDDEDEKPAPSSGPTYPSAFSSPPPKPFSSNPAPIAIPSSPPAHPPSDDDELYA +DLIAAARRAPATTAATPSTAPDPTLTILISSHLPNTTPLLIRRRLNQRLKDVRLAWCARQPPHSGAAATIIFLTYKGLRV +WDTSTCGSMGVKISRAGGVLDDGGGGEGGDVHLEAWTREAFEAHKAAEEARVRNAHLALENEDHGAGGEPAVEVVAEQPV +QEEKLRIILRAKDMPEVKLRVKATTRIADLVAAFRSQREAEVGGRSVELWFDGDRMEEEDCVGDADLEDLSGVDVVVR +>G2XKQ0|reviewed|Small ubiquitin-related modifier 5|taxID:9606 +MSDLEAKPSTEHLGDKIKDEDIKLRVIGQDSSEIHFKVKMTTPLKKLKKSYCQRQGVPVNSLRFLFEGQRIADNHTPEEL +GMEEEDVIEVYQEQIGGHSTV +>A0A0P7V557|unreviewed|NFATC2-interacting protein|taxID:113540 +MITVRLQGKEKGSSQDYSLHKDAPLGSVLSQYLSRMTTGSKSKVRFLFDGSKVAESQTPSQLDMEDGDVIEVWA +>A0A6J2BH66|unreviewed|Small ubiquitin-related modifier|taxID:9704 +MADEKPKEGVKTENNYHINLKVAGQDGSVVQFKIKRHIPLSKLMKAYCERQGLSKRQIRFRFDGQPINETDTPVQLEMED +EDTIDVFQQQTGGVY +>A0A3Q1CST0|unreviewed|Small ubiquitin-related modifier|taxID:80972 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGHC +>A0A9W2WT79|unreviewed|Ubiquitin-like domain-containing protein|taxID:9755 +MAVADEKPKEGVKAESNDRINLKVAGQDGSVVQLKIKRHTPLSKLMKAYCERQGLSVRQIRFRLDGQPVSETDPPAQLEM +EDEDTIDVFQQQTGGVYSKGKLLLYSGILFLRTEKTFSIRKPQFGSTTS +>A0A166PRL9|unreviewed|Ubiquitin-like domain-containing protein|taxID:708197 +MADAAKPKRRLPFKPTALRQKSDPKPALKDNNEDDDDDGLSLFKRSAEFFPVTVAEQERRMKRKQAEREKSSQARSPAGE +TKSTPSASEEPGRRDDEEARYGLSLDFGPPCCNLNDADMAPISREPGTPPSKRSRTSDESPESRIKPSQTKRRDGTETPS +KRITRAAASRTPRKQEVIPTKPVISIDDSDDDPDEDEDRPEDDNDDIYEASPIRKPRRRRQTSEPEVSPLVIDDDDPFAE +GGQGEEAPTPEEEEDDEFKEYVQRAMERKKALEQEASQTVNVFVTSDIPGTKEKQFRFTLVKPLKVLRNAWIDVQDGRVA +LPRSELENVFLTWRGHELYDWTTLHSLDLAATFRKSGGGGGGDASEGFRDDWTNVHMQMWTRELWEEHERQEARRRRHDL +GEYSDDEGGGDGGNEGGTPAVEQEAEKKIKVLLKTKTDDPLKTSVRPSTTIGTIMELFRKMRGLAADAPISLMFDGDELE +EDMTVEDADIGDMETIEVYIR +>Q4QIC2|unreviewed|Ubiquitin-like domain-containing protein|taxID:5664 +MEHPEHSNQRPEGNNNTEAPAPVKAEAAAAVSAQQISLKVVNADGAEMFFKIKRGTQLKKLIDAYCKKQGISRGSVRFLF +DGAPIDEMKTPEDLGMEDDDVIDAMVEQTGGSAVRQL +>A0A9W4JFI6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1612424 +MSDKEAPATEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCDRQGKQPSTVRFLFDGTRVRPEDSPDTVGSIVLFLFFTV +ELLKTNFDKLDMQDGDTLEVHQEQIGGC +>A0A0G4ECG6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1169540 +MADEQGNGGEGAAGGTEHLNLKVKSPDGQEVFFKIKRSTKLEKLMNAYCNRLGQSQEGVRFLFDGERVHPHQTPEELGLE +DGDVIDAMVQQVGGGGGGGYR +>G8BTP6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1071381 +MSDDGDDDDFFMNTDDDPDSYVQEEQVFVNSTEQNITKVVVSEEIHNISKTKVPQTSIFIDSESESETGHTSSSDQNIQK +QYVLEVRKLHTGSKRRESDIKSNSANSTDFSDTGSLEMVNYNNTDRTYRSKRRRSQRENIIDEREIRPSGIDADDEFFKA +IREASKRPSTLSNSGTPEILNRKYNIMYISKLNGSEERRIQAKVLGTQTFAKVLPPILNTLLKVNKIPSKLRSLYKAENV +TLYWNKSKLLNFMNCDSLKIPQTYQNEISELEIILISKEEEQKFEEQFKMQLLEDEQLSQKNIENFNDSNKPFDILNTSY +NEYEKELENWNSKDFNVTNDVLDVSNDENSSNNVKGNDSMNLIEISDNESSIKEHGTSNVIKISLMSNDNKKIFVNVRSS +TKIQKLVDYFKKCKNLTSNQRIKVIFDHDVLSLDSMIGDNDIEDEDIVEMIIE +>A0A0D2H747|unreviewed|Ubiquitin-like domain-containing protein|taxID:1442371 +MASGGVKRPLFSKSAWIAPTAVTPDSGSIFGRNVKYEDIVRAERAEREKKAAKAKARGAGKERSEGSDTKRRRISTEEEQ +DIESGSASEVEHNNRNKKKETKEKARERPVTRSTPTKRKTLSDGLDSSPKTQRSPRRKADVNSTAITLDSGDEDEGEDDD +LIVLTPAKPKASLQKSKVDSFLDERDSEEEEDEYLRLLKQKAREKARLQRQGSQPVRTPSIPPDRGSSATLENAADPRSP +SFVQSQHDSRPASSNSIQDFGAASAGRRSTPNLEQQENDPEVKILIQSEIAGTKSLIVKRKASQSLKQVKEFWCQRFELE +ESVRRQVFFTWKGTRLFDSTTMRGIIRGLKKDHHHRQRQHQQRRSLSLGIDDDEGEGGDEDGGGNDDDGYDSSSTKDPSG +GNVMLEAMTPEIYEQKQRDRERRQERQRSQIEDQDDENEGPSDQDEEKRGSSANAATAPAIEDRDKGAIVIRLVSKNLEP +MPLRVRPHTKIGKIMRGYAAMRKVDDSKTPWLIFDGERLDAESTVEEVGFEDEDEVEVSIR +>A0A485N8Y9|unreviewed|Ubiquitin-like domain-containing protein|taxID:191816 +KHPDSVGLLNVQSNHYLQMVHHLENTQYGNTQITCLPKNPVCLTQPSSNQGSGEGRGICKPWSKLLPTGDRCYVETLGEA +TITMSDQEAKPSAEDLGDEKEREYIKLQVIGQESSEIHFKVKVTTHLKRLKEAYCQTQGVPVNSVRFLFAGQRIAGNHTP +KKLGMKEDVIEVHQEQTGGRSMIYSFFFFTLNPFFIFKNVFL +>A0A395SSJ3|unreviewed|Ubiquitin-like domain-containing protein|taxID:694270 +MSDENANGTPGEQAAANSEHLNIKVTDNNNEVFFKIKRTTKLEKLMGAFCERQGKALSSVRFLFDGTRVQPTDTPDALEM +QDGDTLEVHQEQVGGFSL +>A0A099NSH8|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:4909 +MSLEDTPPTEPLSTLSSITDREKRYKRRGLKFSQEDEPVIEILDTVTDDTNSHQEKRGGDNRGNVDNGEDDDDDPFLKNL +NRFLDSVREDERETVNLLLNQKQEDVKINGQLFEPSTIKFELHVTIQAAGQISGTYELQIKSTTKVGKLISKLLPLFNAD +AETPFPEEEWPSLVLYIEGLNIILDQSLKCISLLAYKNQLKESLNVVGFEVSALITTEKHANYLQSTSMQQRMQANIEDE +DEMGHTIKLTINDLQNNEKTDLEISLKSLLGDLLSLYKYKKRLPQALKIKLLSDQEVEFDEMKTISGYKFEDRQIINVTY +DVWELEELRRQSEFTLGLEMESDEDEAGDDDVGKKHRNIAGGTDPEYFTVYVAGKDKKRYKVDVKPSTKIFEIAKFYIEK +AGLDPNTTLSLIFDDEKLENNSKVGDTELEQDFIIDAIIH +>A0A9P3CC91|unreviewed|Ubiquitin-like domain-containing protein|taxID:84275 +MAENNGTPPADQPDAQQPASEHLNIKVTDGNNEVFFKIKRSTQLKKLMDAFCDRQGKSPQSVRFLFDGQRVNATDTPDVL +DMQDGDSLEVHQEQIGGC +>A0A2K3MWT8|unreviewed|F-box family protein|taxID:57577 +MQSTSVGSKEEGMKVTEEDTHIKLTLKMGHFGSPFVYTMKRSCQFKKLMIDYSDRYSRDFNSVLFSAGRGCIEEEKTPNE +LHLKDGDIIYTNFRSGNIMLKIKGQDGYEASFEMRFNSRLEKLMDFYCRKYCLEVTEVAFLFNGRFLRADQTPSKRAASV +VVGVQDPLRVTKRSVIHCSVILVPNRPGDEIYVVLYDQIDLIELKQKSQMATNVDNSDSKLWPDLETKAFINIMVRKATC +GNMSNDDEWDFMTSELNSITNRTYKKEQLKEKMHRLQAMYHEFNSLLQNPEFKWNAETNTFSASAEVWQNYLQAHDKTAQ +FQKKGCDYYYKWLEIIFNKDNAYGGFRHSDDDIQEVEYATQNGKRKIQVKDRKYRKGSTSCQKGDRHLTSTKPSTARAKS +NNGKSLEATSPHVTLDCSITKCVAALEKIEDISDDIYVKALDKFHDPNWREMFIAMSNDRRRGWLFRL +>A0A443N7R9|unreviewed|Small ubiquitin-related modifier|taxID:337451 +MSGVPGTQEEEKKPMDQSAHINLKVKGQDGNEVFFRIKRSTQLRKLMNAYCDRQSVDLNAIAFLFDGRRLRGDQTPDELE +MEEADEIDAMLHQTGGGHGVA +>A0A251PPD1|unreviewed|Ubiquitin-like domain-containing protein|taxID:3760 +MGVGRRVPVGAQRNMLGVPKRPTRILLLVKDPWENFIVFRIKRSTQLKKLLIAYCDKKSVELDNMRFVHNGRLVRPNLTP +DEHEMESGDVIYAFPVLLG +>A0A8B7IKR1|unreviewed|Ubiquitin-like domain-containing protein|taxID:202946 +MLWSTSSLYNQEEKFLMVESFVAVFNGVFRSLLFKVLLSSLYSASLSIFVQEGVKTENDHINLKVAGQDGSVVQFKIKRH +TPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDEDTIDVFQQQTGGVY +>A0AA39M706|unreviewed|Ubiquitin-like domain-containing protein|taxID:289476 +MSSSDEDDAFNVKALMRKQKKKASNEKQTLTTDDFSCDLDDILDKEKVLNDRIKTDSEDSDTSNDESGKSLTAIERIRMK +KRRNMAKAAQIEKAPEPMSPTSSSSDEDSKRTLRRSARNRKRQNELDSTTSSVECSVENATCKSPARKKISPSKPQDSDD +EICVLSGTMNNVRSFSPEPEEEDMMTVGDGDILEVRYLVKDLSDKSIASFFYPADVKVNDIREKFKNKLDPTLPYLYFFT +EDLDPIDPEKTPIELGWNLSQVHTVRIRQSSHVSFFLAQKQKPKAASDEPCADSVDDGRIQIKFQIKDRHKPFKVLIDPA +DTFGKIKADFCKEQKLDASRCFLIFDNERVADTDTPNDYEMEKNDCVDVHVG +>A0A1V9X708|unreviewed|Ubiquitin-like domain-containing protein|taxID:418985 +MVSGTPIKAEHATDIVGLFLRIGRRAIEYLNGGVHPADECPVHLSLDTKRNMSSDQPAERPGPSNSSGDAKEFIKLKVKG +QEGDEIHFRLKMTTPFSKIKKNYAERVGVAAGSVRLIFDGSPVSDTDTPRGLSLEDDDVIEAFVEQIGGCPNKLRFLARG +AYRLHRNDASVSNTAEMPPTDTNMQAMRTKQHLPARTICTGDVC +>A0A8J5SMQ7|unreviewed|Ubiquitin-like domain-containing protein|taxID:103762 +MPGEEEKKPLAGEQGGGDAHINLKVNGQDGSELFFRIKRSTQLKKLMNAYCDHQSLDLRAIAFLFDDRMLRANQTPDELE +MEDGDEIDAMLHHTGGCVCLQPHYFLP +>A0A3P8K5I7|unreviewed|Ubiquitin-like domain-containing protein|taxID:157069 +MMMAYCDRLGLKQPTVRFIFDGNNIHDTDTPASLDMGEDDTIEVFQTQTGGF +>A0A842P1M2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2026739 +MRIKVRDADTGDTVEMDVTPDIIIEEVLQASCSNWNKEYTAYVLRFGKTQLIPEQTINQAGVRESDILELIPDPLGGHL +>A0AAD9HE08|unreviewed|Ubiquitin-like domain-containing protein|taxID:1216348 +MADAAKPKRRLPFKPTALRQKSDPKPAPKDSNEDEDDDDDDDGLSLFKRSAEFFPVTVAEQERRMKRKQAEREKSSQARS +PDGETRPTPRASEEPGSRDEEEAREPGTPPSKRSRTSDESPESRSKPSLTKRRDGTETPSKRITRAAASRTPRKQEVIPT +KPVISIDDSDDEDDEEDDARPLDDDDIYDASPIRKPRPRRQTLEPEVSPLVIEDDDPFAEGARGEDAPAPQQELEEEDDE +FKEYVQRAMERKKALEQEANQTVNVFVTSDIPGTKEKQFRFTLVKPLKVLRNAWIDVQDGRVALPRTELESVFLTWRGHE +LYDWTTLHSLDLAGTFRKSGGGGVASEGFRDDWTNVHMQMWTRELWEEHERQEARRRRHDLGEYSDDEVGENGGNEGGTP +AVEQETEKKIKVLLKTKTDEPLKTSVRPSTTIGTIMQLFRKMRGLPADAPISLMFDGDELEEDMTVEDADIGDMETIEVY +MR +>A0A4S9AJH3|unreviewed|Ubiquitin-like domain-containing protein|taxID:5580 +MTNFISHPTSEVYDITMDGFNQPPTYPPAPTVEDEPTSIFGGGNAHKAPAADQDTTNAPRDPPTTSDGADARDGNNPGTP +LNDGAAAPTANPDEPRTPDNGAPSAAPAEPVDRVQIVLKDQSGNQIAFGVKSNTRMEKVQNAYAEKTGRPVASLRFYFEG +NRVTADDNVTTLEMENEDIIEVMTEQIGGGGGSDPAPLKLDKYVAKYFSDESLEEVAFVVNKVEVDGKWVKEMEFVVGPD +VKVKDFKDAWAKRAGCSVDSVVFRFTGTKEGPGLPFYTEDETFGDLDLQPDDKVYVSALADEPINLVRPRKSIAVKEE +>K6ZUL1|unreviewed|Small ubiquitin-related modifier|taxID:9598 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A6P8RJ44|unreviewed|Small ubiquitin-related modifier|taxID:260995 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRISDHHTPKEL +GMEEEDVIEVYQEQTGGHSKV +>A0A2P2HYS4|unreviewed|Small ubiquitin-related modifier|taxID:1518452 +MGDNADSKPEGEGNEYIKLKVVGQDSNEIHFRVKMTTQMGKLKKSYSERVGVPVASLRFLFDGRRINDEETPKALEMEND +DVIEVYQEQLGGF +>A0A9D3T9Q8|unreviewed|Small ubiquitin-related modifier|taxID:7932 +MSEEKTKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGSC +>A0A9D4UHM5|unreviewed|Ubiquitin-like domain-containing protein|taxID:13818 +MVQEVVVDDDEDDEFEPLFSYQRVCKPPSDDDSDGDVTVLDPKSMSKKSGNKVFPSALTPTCPPGKRAHEDLTKETEDDD +DWLPPPPKSARALLESKFNEDPTLREIRQAREELMRLAESRIQEDKDSQRSVLQMQEFSAGGEELAGKREKVLVTIQNKD +GACKSFRQLKDEKFEKLFSKYAESIGLPPQQLVFVFDGQRVLEHSTPKDFDMEDEDIIEVNIKK +>N4XBY6|unreviewed|Ubiquitin-like domain-containing protein|taxID:665024 +MTQATPSAAPPKKRSLFKRPAWQDSPKDDDADIFSHSNEFADIIADEARRRAEEKKQEETRRTRKHSQPRDSKRRRTSNP +DDKKATASSTLKTSPKRNKTPLSPLPVQSPPASLAARYDSLATSNSSAVSLPHKDSLVIELGDSEDDSHNVHKSPAPVAA +SHTQNVAVRRSKPSPVVILDDDDEDEAEDEEDSMFAALRARARARIAAKAAASSAQGSDAPKAPITQLLITSRIPNTNPL +MVKIRVDTFIEKPRKAWCAKQGLSQRDTDNVFFTWKGTRIYDSTSITRLGITVDENGHVTIEGDTNIYDDVNLPKIHVEA +WTNELYKEYKKEEAAAAAAKMLAAEAPVVVEERTPTPEPTPVSTKLRVILRAKGRADFGLTVNPHTTIAHIASAYKSQTG +IDKSQPITLMFDGDRLMPMDTVADYEMEDRDGIEVLFK +>A0A2K6RUV5|unreviewed|Small ubiquitin-related modifier|taxID:61622 +ISLMTVEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDED +TIDVFQQQTGGAPESSLAGRGF +>A0A668AKC2|unreviewed|Small ubiquitin-related modifier|taxID:586833 +WRTEPPKCEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEME +DEDTIDVFQQQTGGSFL +>A0A8S1XEN0|unreviewed|Ubiquitin-like domain-containing protein|taxID:43138 +MAEQQQADYLNLKVKSQDGEEVFFKIKKQTQFKKLMDAYCSRQNLQIQNVRFLFDGERILETQTPADIGMETGDEIDVVI +EQVGGQLY +>A0A0C2Y354|unreviewed|Ubiquitin-like domain-containing protein|taxID:686832 +MSDEPNPKIQLKITFEGQSMNFSTKREKPLVKVFNAFSERLNMDNNALRFLLNEVRLRPEQTPAELDMEDGDEIDALLMQ +QGGGLSSSPLISVSQL +>A0A668VD56|unreviewed|Small ubiquitin-related modifier|taxID:47969 +MSDTETKPSSQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKEL +GMEDEDVIEVYQEQTGGLWND +>A0A8S0X4B3|unreviewed|Ubiquitin-like domain-containing protein|taxID:1973307 +MSDNEQNQSNVEPKAEDANATINIKVVSSTGDEVFFKIKRSTKLSKLQGAYASKVGKDVGSIRFLYDGTRISDDDTPQSL +DMDDNDTIDVMVEQVGGYLHVPH +>A0A7E5X165|unreviewed|Ubiquitin-like domain-containing protein|taxID:7111 +MSSSDSEDDCYGNIAQKLQKIKNKFEEKDEKEDEIVLVDTWEVENTATKSNIEDNSSLNLTVTSTDNEEYTLDRSYSETR +SSYKRKVNTPNTSVIEVEDSPLPAPRGRGTGARARGRGARGGPSGRASARGRGRPPRASPRGRTSSRRSRGINSSQQIIN +VGNTYEYPDECEEIELFSGNNDITIVDEQDPLEDDNEEMSVKVYWQSLDVVKFQIRKYQKFTQIFQYFAXKEGVSHNKLL +FMYNDKILKIDDSPESIDYSIAKFIDGGIVNRNVTELVKDKKSTHSIGNGLRVKFQCQNTKKPFETSIPPNENLLRAMSK +CAEHLEVPLQRLKFYFDGDLLTSKSTPQELGLEDGECIDVKIGS +>A0A7K7EY08|unreviewed|Small ubiquitin-related modifier|taxID:227182 +QEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGME +EEDVIEVYQEQTGGHSTV +>A0AAJ7TSH4|unreviewed|NFATC2-interacting protein isoform X1|taxID:7757 +MSRFAASPTIIRLKITASRTLCESRATKEPPGKDEEAGCPSPPLPSGRTLRRQRRPAVGAGQGPSVGAGQGPSVGHPCFG +DIDDEKQRDYLDLEVNDTESCPTVKKMKCVPKPNTNFICISDSDEDLSQEEDSWKNNSPAPPSPPAPRPRLQQRPRRSLD +SKILEVDRLLSACRSEVDTSGLDDSLSLVPPPDAPKEEVTAKVRCQSKVHRIKLLHDECFHSVVSHIAITCEVEPARVSL +FLQEKEISPTDTPLSVQLSITDIIECIITKSALAREGPTHKPANAIALKVQSKEKNSIQIITIGKTEPLSVLMEKYTALV +GSGKQRLVFVLDGADLDGTSTPHELDLEDGDLIDVRVM +>A0A384LQ20|unreviewed|Ubiquitin-like domain-containing protein|taxID:5851 +MADESSAANNTSGATSTQGEHIQVKVRSPDGAEVFFKIKRKTKLEKLMEVYCNRLGQSMEAVRFLYDGDRIHGENTPDQL +GIEDGDVIDAMVQQTGGNLF +>A0A182YP24|unreviewed|Ubiquitin-like domain-containing protein|taxID:30069 +MSDIFGNLDNFLERDASLIKRSFTMLSNSYNRKPPVTANDISLDCDDDDTPIASSAYPYNRPVANRSTANDADTITLDSD +DELSNRANNSFETENYEMRVKVKWGLGIETFVHRRYQKFADIIGQLAAKESADSACIFLNLDDRIVYPTDTPDSISYKPH +QFISGRILKSKAPILPSAVAYSAAGNSSSITLKVQMATRKQPLRLQMEKSQTMSVLAIKCAEELKCAPKDIRLYFDGELV +DNGCKPEDLDLEGDEILDIRVVQ +>A0A8V0ZWF7|unreviewed|Ubiquitin-like domain-containing protein|taxID:9031 +GPPVARAPTGHVAGGASYGCAQWAGCAERYVRGRQFSGGGYLRGRAAGIAVALCKFLPINRGLPGRAVTEGRAEAKPSAE +DLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVY +QEQTGGHSTV +>A0AAD6JF56|unreviewed|Ubiquitin-like domain-containing protein|taxID:889485 +MSGATGQPQEEDKKPNDQSAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFNSIAFLFDGRRLRGEQTPDEL +DMEDGDEIDAMLHQTGGAVKTTPTKSFDSNCTILLGLDLQCLVCWDMAHLSLPLLSLLTSPS +>A0A9P5TQM1|unreviewed|Uncharacterized protein|taxID:109634 +MSQEPEDVKPKLNLNIAFDGQQITVKVKVNMKFAKIFEAAEKRFGKDSAMTFSTRREKPLVKVFSTFAERMNMDTKTLRF +YLNQDRIRPEQTPAELNMEDGEEIDATLMQRKRVGVVVYQHWSLLHRITLGWPHYESENEIGAPSSRYQKFNHGFRDVVQ +RNTGLLLFVASQAFYSMMDTAVKVLHGIDPPVTTLQLIIVRMSITFVCCMIYMHIAGIPDPLLGPKGIRHLLLLRGFGGF +FGLFGIYYSLQYLSLSDAVVLTFLTPTCTAIAGSAFLGEGYHLRQAVASLVSLAGVILIARPATIFGHPSDLPGGNRPGE +TVSAAHRLLAVGAALLGVVGSSTAYTTIRAIGKRAHFMHNMVFFSMVCVVVSSVSMVVTRTPIIIPRQLDWLSLLVMIGI +FGFVAQMLMTMGLQRGAAGHVTMALYTQIVFAVILEYIFFHTIPQVLSIIGTTMIITSAIYIALTKRNEKTSPIPTFSSE +RDGLERPLLSEDVSPTYDGRTSR +>A0A452SQ99|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9643 +MRRPCAHRTRRGLASHASQKPEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQT +GGSRESGCL +>A0A1Q3EK29|unreviewed|Ubiquitin-like domain-containing protein|taxID:5353 +MSQEPADVKPKLNLQIQYEGNQVTVKVKADMQFKKIFKAAAIKFNKEEGTLKFTYDGNRIQEDDSPAGLGMEDGDLIDAF +LEQLGGCRCITPHSETR +>A0AAD8SY03|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:4521 +MGGGEEVPPTAAADSEELEPLFDYSRVRPTFDFRFDDSDLEKSDIFVHCNKRPKLADADADDAAAFGDKASEKGDAGVKK +AAVVNLDDEDWLAPPPLKPVAMAAICKDKTLHEPRLENQEVAKLAEDTFQKVVETVKKDLAAKKPPESIVLDEPTEPQLK +KTKEKILIMIQDKDVQQPFRVCKDEKFDKLFKAYAKKNNLDSSNLTFVFDGVKMNPASTPQDLDLEDEDLIEVCYKPAEP +VIHKPTEPHVKKAREIIPITIQGKAGKHQFRVYKDDKFDKLFNAYAKKVQLSPSDLTFTFDGDKLNSASTPQDHDLEDDD +MIEVCCKSS +>M2YJU5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:675120 +MSFFKAPSWARSQTVKAEDKSERNIFSHSDTFLDLQKERIEREARRKQKEKDKEERRKAKQEEKRRSSSEKRKVMEEDGN +DSLKKRRITAEDGAKLLVSAGLGDSITISDSEDDAQAHLPIRRSPRTIRMHNVLSPSKMKGRPAAPPNVDEEEDLYATSI +PPRPVRPQAHSRPEVEEEVDSDPEIAEIQRKARAAARLKEKAKIAQSATPEQGTPGIDDSFENSHLPITPVYDAAVQLLI +ESSIPDTAPLIVFRKLSQPLREVKKSWCKKQNFSEEFSKQVCLVYNGRKYFDSSTVQRLGISADANGRVFLESDPTAEGV +EKVHMLAMTEEMYEQFKEERERQARAETGDYEGGQDEAEAGDDEEVPAPRRSIKLIVKAKDRKDYKVQVFDDTTFQKLLR +AAKKVFDLGPEQEAYLELDGERLDPEDEVGNTDLEDMDQVQMVLVR +>A0A5N5M840|unreviewed|Ubiquitin-like domain-containing protein|taxID:1571157 +MAEAPQSPNNNQNTPGAGGDDAPPAAPEHLNIKVTDNNNEVFFKIKRNTKLEKLMLAFCERQGKTLTSVRFLFEGQRVQP +TDTPDTLEMADGDTLEVHQEQVGGC +>A0AAD4NA86|unreviewed|J domain-containing protein|taxID:166010 +MSDGSDSDGDYYSANFKRFKEKRQKNALNNSHTSSQVQSIPIVTVEKQKVEPKKRKKDVRKGDLSPILNKTNDEPLEEIV +VLDTNEDTSCLSIQSEILTDSSVSIPSCWVHFKNIFTCDKVVIMCEMDRTFSSIIQENASRIGVDPDKFLLMGTDRRFYP +NESPQSVGFFPDTVYSLDICEDGSATGEVITIKWQLKGKKPIQANILIKQKFSILKSNLCKEHNLDPNKTCLVFDADKLD +ENSCADDEDAQMRTVYRTGCCLLEKQHPKLYLLHCKRFYGSGSDGSDHYKTLGVERSASAKEIKTAFYKLSKIHHPDANP +KDPVKSAQSFRKVVGAYEILGNTDKKRDYDMQFNRGRARGTIVLNQHGRSASAPRDRSYTDLDIDFKDFEHFVRSTRKRR +RILYNEFEMPEYFKNIHETHDPRTSRGPTYMNYKDSRAFQREEEERRLMRELEELKKKDCFTMPSFDELLRKEQRRRRER +IKALTILMMEFLIFADEPMGGYGVNDGCVLEIQASDNFSGTLKPSAEEAKLHAEDWPLLLKNFDKLNIRTSHYTPLVEGC +SPLKRNIKDYVSAGYFNLDKPCNPSSHEVVAWVKRILRVEKTGHSGTLDPKVSGCLIVCIDRTTRLAKSQQNAGKEYVAI +FKLHNPVESEKVIKRSLDKLTGALFQRPPLISAVKRQLRIRTIYDVKLFEYDPEQQMGIYWMSCEAGTYVRTHIVHLGLL +LGVGAQMQELRRVRSGVTSENDSLVTLHDVLDAQYLYDHHKDESYLRRIIRPLEALLVQHKRIIVKDSAVNAICYGAKIL +IPGILRFENGIELNDEIVIVTTKGEAVCIAIALMTTSTISITDHGCVAKIKRVIMERDTYARKWGLGPFASKAKEMVKSG +LLDKHGRPNEKTPKDFLKMYEDHSVSGGNNSAKKVEKKEEMEEDDDE +>A0A915CXE1|unreviewed|Small ubiquitin-related modifier|taxID:166011 +MSESGDQTKTTEAGAQVVGQDSNEVHFRVKFGTSMGKLKKSYAERTGVSVNALRFLFDGRRINDDDTPKSLEMEEDDTIE +VYQEQVGGMVQQVHSCC +>W9XQL6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1182542 +MNTGVKRSLFTKPAWAAPAASSSKIEDDGSVFGRNVAYDDIVQAEQAKRERKAAKAKLHADKGKSVSPSTKRRRISVEKD +NEAASGSGSDTGVASRRRASDKSRRGRDRPVTRSTPWKDMTLETGSLSRSPTRSSRSPRTGHHATSAVASIAVDEDEDDA +LVMLTPSKPKKTAPTRPTASLPVDDDESDEEDEYLRDLKQKAREKIRLQRLGLDLDRAQSPLTSTSSAPTIPRGLSTEQS +QSRPVSASSGQDFGRATPASEQEDDPQVKILIQSDIPNTNPLIVRRKASQSLRQVREYWCKRWQLDDSVSRKVFFTWRGT +RLFDSTTMRGIIKKLKKDHRQQSTGLDEGDDSEDDGDEEEEDDPSSGNILLEAVTPEIYEEKLRQKEQRQNRASADEDPD +SSEEAAVSSRAQTDDRDTAGSIVIRLVSKAHEPLQLRVRPHTTVGKIMRGYAATKKLDDGKTPWLVFDGDRLEPEATVQD +VGLEDEDEVEVNIR +>A0A1Y3BVY9|unreviewed|Small ubiquitin-related modifier|taxID:6958 +MAEDAKESLPEYIKIKVVGQDTTELHFRVKKTTSFSKLKKSYSDRVGVPLSSLRFLFDGRRIDDSDTPQSLEMEEEDVIE +VFQEQTGGGGGYSIFMNQI +>V4LSJ9|unreviewed|Ubiquitin-like domain-containing protein|taxID:72664 +MSASDEKKPSVPSSHVTVSISTQKKEMSVYFRIKKDVELCKMMKAYCDKFGIEMSTLRFHFDGDRIKPNQTPSELGLEDG +DEIDAFFDQDGGRSFCYRY +>A0A8J6EQL0|unreviewed|Small ubiquitin-related modifier|taxID:57060 +MSDQEAKPSSEDLGDKKEGGDYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADHQTPKE +LGMEEEDVIEVYQEQTGGHSLI +>Q5I0H3|reviewed|Small ubiquitin-related modifier 1|taxID:10116 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEL +GMEEEDVIEVYQEQTGGHSTV +>A0A0G4KMK9|unreviewed|Ubiquitin-like domain-containing protein|taxID:100787 +EAVEHLNIKVTDNNNEVFFKIKKSTKLEKLMNAFCDRQGKAFNTVRFVFEGQRVQPTDTPSALEMADGDTLEVYQEQVGG +C +>A0A6J1AXG5|unreviewed|Ubiquitin-like domain-containing protein|taxID:108875 +MSRPSGQASNSADGQPESIKITVKGQDGSTVVYKIGRKIKLSKLLHSYCQRKQLDYRTVRFVHEGHHVPGQHTADKLKLE +DGAEIFCMFLQTGGGIHIMPKTT +>A0A8D2CXT5|unreviewed|Small ubiquitin-related modifier|taxID:55149 +MADEKPKEGIKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A7R8CNS7|unreviewed|SUMO|taxID:72036 +MRYCICWIVWHELLFKICAYIRKVKEDLVSLDGAGVNGFLWRWELLAARCNFKSSGSLCRLFFSLESPLFLGKWKMSENK +DETEYIKLKVVGQDSNEIHFRVKMSTQMGKLKKSYSERVGVPLSSLRFLFDGRRINDDETPKALEMEQDDVIEVYQEQSG +GGKRPFHPF +>A0A9W9R0K3|unreviewed|Ubiquitin-like domain-containing protein|taxID:5074 +MSDKETAPTEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCERQGKQPSTVRFLFDGTRVRPEDSPDTLDMQDGDTLEVH +QEQIGGSC +>A0A6Q2X1D7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:8010 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGLC +>A0A167H5K6|unreviewed|Ubiquitin-like domain-containing protein|taxID:1081107 +MAEDNGGLPGGEVPAAGTEHLNIKVTDNHNEIFFKIKRTTKLEKLMTAFCDRQGKSMTAVRFLFDGTRVQPSDTPDNLEM +ADGDTLEVHQEQLGGAGL +>A0A8C6G7K5|unreviewed|Small ubiquitin-related modifier|taxID:10103 +MANKKPKEGVKTENNDHINLKVVGQDGSVVQFKIKRHTTLSKLMKAYCERQGLSTRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A9R0KAU6|unreviewed|Small ubiquitin-related modifier|taxID:3562 +MTGEIDNNNNGGNSAFNEDKKPATDQSTHINLKVKGQDGNETFFRTKRTTALKKLMGAYCDRQSVDVESIAFLFDGRRLR +GEQTPDELEMEDGDEIDAMLHQTGGY +>A0A6G3S998|unreviewed|Ubiquitin-like domain-containing protein|taxID:2706073 +MSDTRIRLRVRSADGREHAFPVSATDPFQGIMQRYAEVTEQDQAGIAFTYEGTRLLSTSTPHELKMSDDDLIQAETAPEP +DRQDS +>A0A081A412|unreviewed|Ubiquitin-like domain-containing protein|taxID:1317066 +MSEEATPNTNATNEEDKKKAEAITIRVKDQSGEETFFKVKPNTKMDKIFSAYAQRKGVPASALRFLLDGTRISGDQTPKM +LELEDQDQIDCALEQVGGFRC +>A0A7L3UKK5|unreviewed|Small ubiquitin-related modifier|taxID:13746 +SPPRVFQEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINEADTPAQLEMEDE +DTIDVFQQQTGGAC +>A0A8C2NRM5|unreviewed|Small ubiquitin-related modifier 1|taxID:9925 +MTTHLKKLKESFCHRQDIPINSLRLLFEGQRIVDNHSPKGLGIEEDVIEVYQEHTGAHSAI +>A0A1S3AMZ5|unreviewed|Small ubiquitin-related modifier|taxID:9365 +MANEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHIPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A7S0XC21|unreviewed|Ubiquitin-like domain-containing protein|taxID:81844 +PAPTSPVELTLGVVQSVSPRGTTATVTLGGDVFGRGRSSRAADLPFGGRLIPDYVAILQELTLNMGNPPSIDLDVTFPKT +EVVDLGNRVGDFWVNSLIVVALRRGHPDVDLANPDTYTLVKVSSDSSSVTARLCEESTSHVNRSLFCSLVAANTPRSSDA +KSISVHMGMTAEMRAQTWRAENPGHSVHVELRLKDQDDSEVHFKVTFTCPMSKIFDAFCSRKALNRDSVRFLFDGTRINP +AMTPADLEMKAGDVIDCMMEQVGMHVRCNGRDGNEALTGNVNVTVCVPGETHVTVSIKEQQTLKEATTMAALQAPTTSTM +AALQMQLELAQTQATEAHATIAVIKTRMKEVEGAGARKRTRADFA +>A0A6P5TQV8|unreviewed|Ubiquitin-like domain-containing protein|taxID:42229 +MSGGRSDEDTVNLKIQFNKDGVQTLFRIKRSTKLQKLMAAFCKNRSLDPKSVEFTFDSVRLEKNKTPEQLGMEDGDLIDA +LVSGDGA +>A0A9P8EY81|unreviewed|Ubiquitin-like domain-containing protein|taxID:46634 +MTARQRYQICINDDRNLYVWKDTWKEDTIADFLTRLSNSTNPRLDRQRIHLSFDGVRLGESTTMRETGLEDGDELALHYG +SSSCKLCTGSHNGTGYMTRQRG +>A0A834MUE6|unreviewed|Small ubiquitin-related modifier|taxID:30212 +MSENQEQKPEAGPGDANSEYIKLKVVGNDSNEIHFRVKMTTQMGKLKKSYSDRVGVPMTSLRFLFDGKRINDDETPKQLE +MENDDVIEVYQEQTGGLY +>A0AAE9JPW7|unreviewed|Small ubiquitin-related modifier|taxID:6238 +MADNGAAAAAAPGKDNIEYMKIKAVGQDNSEVHFLVKSGTSMAKVKKSYADRTGVSVGSLRFVLGERHISDKDTPKSLEM +EDDDVIEVYQVQTGG +>A0A2K5E4N8|unreviewed|NFATC2-interacting protein|taxID:37293 +LRKSEPLQSVVDHMAAHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVLASSPEATETSQQLQLRVQGKEKHQ +TLEVSLSRDSPLKTLMSRYEEAMGLSGQKLSFFFDGTKLSGRELPADLGMESGDLIEVWG +>A0A7S1S014|unreviewed|Ubiquitin-like domain-containing protein|taxID:2925 +LKPWPSAPLSPGGAASSVPFHNPRAMGGDGEAAGDAPAHIQLKVKDQQGSEVQFKIKKSTPLRKLMDAYCSRLGLQASQV +RFMVDGERIAPDDTAEKLGLEDEDLIDVAMEQTGGHC +>A0A2S7QG55|unreviewed|Ubiquitin-like domain-containing protein|taxID:2070414 +MSDNEGSPAGEKPETPVASEHLNIKVTDNNNEVFFKIKRSTQLKKLMDAFCDRQGKAPNSVRFLFDGSRVQPTDSPDKLD +MQDGDTLEVHQEQIGGAF +>D3TQD5|unreviewed|Small ubiquitin-related modifier|taxID:37546 +MSDEKKGNETEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIE +VYQQQTGGSNN +>A0A8C9E0M6|unreviewed|NFATC2-interacting protein|taxID:42100 +MAGRLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVLASSPDVAEKSHLLQLRVQGKEKHQLLEVSLPRDSPLK +TLMSRYEEAMGLSGHKLSFFFDGTKLSGKELPADLGMESGDLIEVWS +>A0A9W2X2N0|unreviewed|Ubiquitin-like domain-containing protein|taxID:9755 +MTSTQSQELLSGLRKPGKLKQPSWCCLCARSVRTWYLFWEAAAEEAPALAVTNEKPKEGVKTENNDRINLKVEGQDGSMV +QLKIKRHTPLSKLMKAYCERQGLSMRQISFRFDGQPINETDTPAQLEMEADVFQQQTGGVY +>A0A4X1V599|unreviewed|Small ubiquitin-related modifier 1|taxID:9823 +MTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0A9N8VJC5|unreviewed|Ubiquitin-like domain-containing protein|taxID:27381 +MSEQNQAPPTGDEKKGDSTEHINLKVVGNDHNEVFFKIKRTTQLKKLMDAYCERQGKSLASLRFLYDGERVQSHNTPHEL +DMEDGDAIDVMVEQIGGLIFYKI +>A0A8E0RSE0|unreviewed|Ubiquitin-like domain-containing protein|taxID:27845 +MGDGANNTAKDSSSEHINLKVQGQEGSIVHFKIKKSTPLRKLMNAYCERMGYQPMSVRFIFDGNNVHDTHTPASVSETFA +ADGILLVGNGRERHN +>M4F3B0|unreviewed|Ubiquitin-like domain-containing protein|taxID:3711 +MRPRSLFQSFYYSPSLDILQSQNFFLHRSEFLFSTPTGESGKSKMSATQEEDKKPGDQGPAHINLKVKGQDGNEVFFRIK +RATQLKKLMTAYCDRQSVDFNSIAFLFDGRRLRAEQTPDELDMEEGDEIDAMLHQTGGVAIC +>A0A8C0Q4V5|unreviewed|Ubiquitin-like domain-containing protein|taxID:9615 +MLVSYCERQGLSMRQIRFRFDGQPINETDTPAQLAMEDEDTIDVFQQQTGGVY +>A0A836KSB5|unreviewed|Ubiquitin-like domain-containing protein|taxID:5663 +MENQDHSNQHPEGNNNNAAPAPVKAEAAAALSAQQISLKVVNADGAEMFFKIKRGTQLKKLIDAYCKKQGISRGSVRFLF +DGAPIDESKTPEDLGMEDDDVIDAMVEQTGGSVMRHLCRPTSLSMCVYTCVRA +>A0A7S1SD89|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2925 +DSSANDTAFEERRRVADGKYAAETAQGYIHLTVKSKDGVTLHLKQNKSVHLMVVMTMVSNRLKYPLDVANFTFNDQELTV +HDKPEEVGLKDGDVIDVRLLSNEEIGMKTIRDRAHKNALEQQRREEAVAERRAAEKAKHEAATLEKTRALERKKAEAEKV +AKQEAKEQERQQFEEEKQAQREAKAQHLDELAEKKRADAAARKREHEAQKRKLEEDAKQKLLLKAQTKADEEVKRATEAE +AKRLADEKAQQEAEEAAARQAAEQEKKDAEDRKKQREEEYQKMVDQKAKDKAQAISDAKAAEEARKRDREEATQKAQEAA +AKEKARKEAERLEAKRIENEEAAIKAEEEAQRKADALAQKKTEDEAKRKAEEDAFLAKKQADAEERARAKAEKERIKLER +DDAYRTMMWEREAAVKEAKAKKAEDAASRQAEEDAKQKAKEDAKLKAVEEPLAGDDGSSGSSGSGSGGQALF +>C5KAH8|unreviewed|Ubiquitin-like domain-containing protein|taxID:423536 +MSDSPAENHNGEQQEQHENKEQGEQPQSLQLKVKNAEGKEVMFKLKRGTPLRKLMDAYCTREGLPSDGVRFLYDGERINR +DNTPQELDMQDQDEIDALVEQTGGCSLL +>A0A8V1ALR1|unreviewed|Ubiquitin-like domain-containing protein|taxID:9031 +QIFLLLCWERWPHRSETVHISQQTNPFLGKSRSWLPPALRPYCLQPQSTQCYSWGGRGVRRQEGVKTENNDHINLKVAGQ +DGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDEDTIDVFQQQTGGVY +>A0A4W5QVA2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:62062 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGQLLLLRLPHRLCVSLFLF +>A0A673N9T8|unreviewed|Small ubiquitin-related modifier|taxID:307959 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINESDTPAQLEMEDE +DTIDVFQQQTGGAC +>A0A484BII8|unreviewed|Ubiquitin-like domain-containing protein|taxID:7232 +MADDAELHIRCPHITLKMQSADRGVVLFRIRRVMPLGKLKDAYCSQMGLAKDLAMLSIDGEQISDSETANSLELEDEDIM +DVQLKRQSEAGDAPACALDLSI +>A0A1D1Y0Z5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:1678845 +GARANLWQYPSAPTHTATVVEPTSPTAFLSALGTLIPGMEEVQEELEPLFDYSRVQPADFISLDEDDDLDSHPFSPDAKR +KKFAKDVGKEDDKVVILDDDTGEGEVEEDWLPPPPPEVVNSSLELAEDSTLRELRLKKQELASFTRSAEDVMRAVIESAK +RERKSLGKSDDLEPVVEEPVKPKVDRPKILISIQGKDGHKQFRVYKDDKFERLFKMYANRINCNLECLVFCFDGDKVNPS +ATPHSLGLEEDDIIEVHIKSH +>A0A553NYK8|unreviewed|Ubiquitin-like domain-containing protein|taxID:6832 +MDSDSDYEVEFLTNALQQTQGHVRQEFHGQGGSPRSENDSAEEEGDHHTSPPAKRVKVCRPHPGILPPDEEIPSTRVASS +SSYSNSSSDSEVTPPPTPENPVQTPILHSQLDHGHVTRSQARSELSQPNSRGRGRVRGGLRSRRTDMALSRLRLERMERL +NRHRDLEVDEKTDREETEDGDADGQMVCQGSQSFEMKVRWRHAIIRDMVDRNDTFADILERLALKIDIPVRGLQLRLDPD +ILKPSETIASRHVGVASILSLEVAPSMLKDSFDDFNNQDLIELKCQASDRRSTVMIKLGPQDPMSRLMEKYSELKKCPLN +TFRFTLDGQDLNDDDTPLSLDLEGGECIDVIPV +>A0A815AVM1|unreviewed|Ubiquitin-like domain-containing protein|taxID:392033 +MFSSAEHRSTDQVSLTVVRKSDGQSVTFVLNEKTRIHDLKHELKRRLKPRFDRGCRLIFRNQVLKGKHTLKHYGIKKGVN +DQAISMDDTKDSKSSSSSSSSSDSE +>A0A453F145|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:200361 +GTPTPMSSPLLLRTEAHEEEMPAAGADSEELEPLFDYSRVQPTIDFCFDDSDLEESDIFVHCNKRPKVPAAAADDANAVE +GGNANEKGDAGIKKATVVNLDDEDWLAPPLLKPVLSTEVCKDKTMQELRLKKQEVEKQADDAFQKVVENVKKDMLAKKPP +EPIVLDEPTEIETKKSKEKICIMIQEKDGRQQFRVSKDEKFDKLFKAYAKKVQLSSSDLTFVFDGDKINPASTPQDLDLE +DEDMIEVHHKPTLDKPAEACVKKSREKILIMIQDEDVKLQFRIYKDEKLDKLFKVYAKKVQQSPSDLIFIFDGDKINSAT +TPQDLDLENDDMIEVRHKSR +>G3QHU4|unreviewed|NFATC2-interacting protein|taxID:9595 +MAEPVGKRGRWSGGSGAGRGGRGGWGGRGRRPRAQRSPSRGTLDVVSVDLVTDSDEEILEVATARGAADEVEVAPAPPEP +PGPVASRDNSDSDSEGEDGRPAGPPREPVRRRRRLVLDPGEAPLVPVYSGKVKSSLRLIPDDLSLLKLYPPGDEEEAELA +DSSGLYHEGSPSPGSPWKTKLRTKDKEEKKKTEFLDLDNSPLSPPSPRTKSRTHTRALKKLSEVNKRLQDLRSCLSPKPP +QGQEQQGQEDEVVLVEGPTLPETPRLFPLKIRCRADLVRLPLRMSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTAT +PRTLKLGVADIIDCVVLASSPEATETSQQLQLRVQGKEKHQTLEVSLSRDSPLKTLMSHYEEAMGLSGRKLSFFFDGTKL +SGRELPADLGMESGDLIEVWG +>A0A836IX12|unreviewed|Ubiquitin-like domain-containing protein|taxID:2802991 +MENQDHSNQHPEGNNNNAAPAPVKAEAAAALSAQQISLKVVNADGAEMFFKIKRGTQLKKLIDAYCKKQGISRGSVRFLF +DGAPIDESKTPEDLGMEDDDVIDAMVEQTGGSVMRHL +>A0A8K0TEH3|unreviewed|Ubiquitin-like domain-containing protein|taxID:40658 +MVDVSAPPKRRLPFKPTALRQKKEPKSDKIEIEDSSDSDGGLDLFKRSKSFFPKALAQQEALRKRKSSVEDVKPPTTPKN +KGKQKETWPPLKQSPDADRRSKLPPIKLSDESDDPDSVKTPPSKRSRHSLSSVASHSGGRRDRDKTRHDASPSKSASKSI +PCHSPRVKSESFHGNPVIALNDSEDEDVKPTIHNDDIYEATPIRKFRHSPVPEPVVTDIPSSPEPFLSDKDDDTDEFAEF +VRAARERQEKAKEASSQNQSEKPTAILLFVTSEIPGAQERKIKCGLDKRFHIVKEAWCAGQHLREFAAEEQEDIFLTFRG +RRLYDSTTVASLGVRITATGELALASAQSWSDREGILDSMGALQIEAWTEETWEVAQKQKERARLRDLGELDDDSQEGDG +ADEEEAPEPEEETIKVILKTRDNDKETVKARARPLTTIDELIVYFRRARNLPETTPIVLQFDGEQLDGATTLQDAEIEDM +DAIEVHIKG +>A0A9J7LZV5|unreviewed|NFATC2-interacting protein|taxID:7739 +MAEADCAEISSSAQDSLKNGKKSSVFQDDSSSSDSDEEERIVVTKKPPPRRRKFNMNASAAKTGNIYIGKVKQDLFSVNM +AALSDKHDSDEENNGGNVVFLPSKSKVRKTSPADQVNSRTEDPSTFVISSDEEELSTDLRSPEDRRHVTREQSPSPPPPP +SFDTLLHDVGRLRATKARKGTEKVLRGVDAALQTVRRTAEPAGLSSPSSFSLDSSGLASPVTPVDREITVKVRSRSSGAG +VHRINMRMSDRFEKLFRCMSEREGAPTDRVLLVLRDYTIQQTDTPQSIGLHIADIIDCSISNASMVVEEEEEETSTEGKL +ELKIQGKERKTEKTFTVDKSEKLQRIMQEYADFRQLPLSRLHFKFDGESVSPDDTPEDLDMEGGETIDARALQ +>A0AA39DIW8|unreviewed|Small ubiquitin-related modifier|taxID:103349 +MSGVANPSSQDEDKKPNDQSGHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDLNSIAFLFDGRRLRGEQTPDE +LEMEDGDEIDAMLHQTGGACV +>A0A6B9VGS3|unreviewed|Ubiquitin-like domain-containing protein|taxID:3818 +MQDDEFADELEPLFDYSRVQPPVISLDDEDDDADKDVVPPKKGKTSHDPVVPEKKQTDVKPVPVVDIDDEDDWLPPPPKV +STDAHKSIDEDSTLKKLRLKKQELQDLFKTVEESEKSEICDSPKSSMDDTSEKTSKPAERPKILISIQDKSEKKPVRVYR +DDKFERIFKMYAEKLGCDQNKIVLSFDGDKISPSETPDTLGMEDGDMIEVHVKSS +>A0A0D0AFC0|unreviewed|Ubiquitin-like domain-containing protein|taxID:930992 +MSEDTEDVKPKLSLVINYEGTQITVKVKHIMPFKKIFDAAEKRFGKEPGTFKFTYDGKRLRAENTPMDMEMEDGDIIDAH +LEQLGGGPIIC +>A0A8C3WVS7|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:51154 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQLGMEEEDVIEVYQEQTGGHSTV +>A0A674J6A4|unreviewed|Ubiquitin-like domain-containing protein|taxID:2587831 +FPDAELGSGRKTPARLTRPETTVRPAEGRAQQRPAAPRSCCRRLLPAELPREGRTDGGREAATPGGREVSSARRKSRPPG +LCCAAEGQRKEPSDRAGLAPETTGKAMSDQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQR +QGVPMNSLRFLFEGQRITDNHTPKELGMEEEDVIEVYQEQTGGHSTV +>A0A2U4BMB6|unreviewed|Small ubiquitin-related modifier|taxID:9739 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A8C1ZEM6|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:7962 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQVRSRPATHSHSHTYTHTHTRTHSHTHTLA +RTLSHTHTLTLTHTHTLAHTRTHTHTHTHSHSHTRTHSHTLAHTHTHTLTLTHTHTHTHTHIHTHTYTHTHTHIHTHTHS +LTHTHTHTHTLAHTHTYTHTHTHTRTHTLAHTHTHTLAHTHTLTHTH +>A0A3M0WH54|unreviewed|Uncharacterized protein|taxID:2249417 +MRSRSGSTTSVTSTKELSADNIPINVSICDDKTIKLNIRPIHTVSNILEFLSASTTLPTDVRLVMDGKPLDPPSTVAQLK +LQESSVLKLDPPSRRSASPTQEPAATPAASSPSDSHTSTTPATAAPASTPRTGTPSKRPSRPRCSKADCKALAPPIVGDC +GFCQKRFCGKHRMLESHNCSGLQNARQADKDRNAAKLQSERTVMLRGL +>A0A6J5VDM6|unreviewed|Ubiquitin-like domain-containing protein|taxID:36596 +MDHHHIHTPAATLDKDDDVEETATLSHTKNSAASSCSSRLSHLPTGGEDEEDPTTLIRVRAQQHPPVTYLMGPNSLLQHI +LRNYRTRNSILYESERFIYNGNRVRQNHTPADLGMEDGDAIDAMSHMLGGGAAVT +>V7BPK6|unreviewed|Small ubiquitin-related modifier|taxID:3885 +MSGVTNNNNEEDKKPSEQGAHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVDFNSIAFLFDGRRLRAEQTPDEL +EMEDGDEIDAMLHQTGGSVF +>A0A4S9WE33|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:5580 +MAEPKPKRSLFKRPTWAAAATPAAASASPDAPAKPEEATDIFSHSSTFGEIVEDRQRQRRKKSDKDTLRRSQTNEVKDEE +PRAGKRRRISDEDGTELSTKTSNKDTKSKTKDTERRASTQSNGASESFAIAPTPQKSKPRQEAVIELLDSDDDNEPVSFN +NGLQSFTPSNATSLEPTPAADPNPDDDPDAVYYSDPEMREFVRKAREKRRQQEREQSESGAHDPTVKLLITSPLPNTQPL +IVSRKLSQNLQQVREAWIGKQDLLDPSTASRIFFTFKLRKVYDVTTVRSLGIKVDSYGRIMTNGPFANTDDDHAEKIHIE +AVTEEAWQELKDKKAAPKQNKYLNNAAFADNRGLSAEGTPAVDGEAAVEEPLIKVTLKARGHSDIKIKVRPSTTFMKMIN +AARRSFKLDPDRQLHLEFDGEKLEPPEGLVKDTDISDMDCIDVHIK +>A0A6G1JC90|unreviewed|Ubiquitin-like domain-containing protein|taxID:1168545 +MSDNGSPAQQKPEDGGQTEHLNIKVTDNNNEVFFKIKRTTQLGKLMNAFCDRQGKNISSVRFLFDGQRVQTNDSPDSLDM +QDGDTLEVHQEQIGGC +>A0A559MN20|unreviewed|Ubiquitin-like domain-containing protein|taxID:215461 +MAGDIAQAVTEPSEPPPKKKSLFSKKLIAQVAEDAEGVAFFSRSSELFPQRLAEEEQRRQKKALKLERKRSSASLEKKEP +SPQEEKRRRISKDRDLYSSEEDAEASWARRESTTSTPGSGSRKSRSASARKNQASPPTSLAVRYSRDLRAAKKEEPVVKP +ETKGYISLSESDDEDVKPVRARNEPIVLDDDDIYSIPQKPKPKPVELDPELSDEEFPELLQQARERERLKALAREKESKS +FKEQNHTSNDLDDDIFQTESSKAVVDPIIEVLVTSKIDDTKPLLVKRKVSQRLKEVKTAWCDHQTNDGQPMASEIKDSIF +LTWNGKRLYDVTSCKSLNLNIDSSGKISSQGEGVDFNGRVHLEAWTEDSFKAHQNKEAARLQREQDGADEDEEEVIEEQV +VKKIRLILKSRELGESKMTVKPTTLIQKLINAFRQDKKVAEHQDISLQVDGEKLDPEEKIEDTELEDMEVVEVHIR +>A0A8X8ARF0|unreviewed|Ubiquitin-like domain-containing protein|taxID:52824 +MSAAQEEDKKPGDQGPAAHINLKVKGQDGNEVFFRIKRATQLKKLMTAYCDRQSVDFNSIAFLFDGRRLRGEQTPDELDM +EEGDEIDAMLHQTGGVANGIFYRDKLIMMALSSSFSSSSWSDLLPELMDAVFHSLNDARDILSCATVCSSWRYSSSAVYS +RKFVPLLFVSHPSSANEETKFSDHFRVITIRDGFAEAQEIFVNRHCFFPARAVASVPSYLSALWSPNPNKGVCKEK +>A0AAD9U6W4|unreviewed|Ubiquitin-like domain-containing protein|taxID:168575 +MSATGGGGGQEEDKKPMDQGAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVELNSIAFLFDGRRLRAEQTPDE +VWLLLCMLIYYGVCLYSSTFYGISSRWRMEMKSMQCCIRLEEGLKFVKCKLKYMGHVPGLLMSSFIFATPLEILL +>A0A507CMK6|unreviewed|Ubiquitin-like domain-containing protein|taxID:286115 +MDGENFEEQKKVEHINLKVVGPDHSEIAFKIKRTTPLDKLMNAYLQKTGQDRNAVRFITANGDRIQPSDTPEDLELEDGE +QISVTVQQLGGHVY +>A0A8I3A620|unreviewed|Ubiquitin-like domain-containing protein|taxID:495285 +MTEVDSTLAASQNEVKTEENAPINVKVVSSTGDEVFFKIKRNTKLSKLQGAYAAKVGKDVSSIRFLYDGNRINEDDTPSS +LEMEDNDTIDVMVEQVGGWAP +>A0A074VW53|unreviewed|Ubiquitin-like domain-containing protein|taxID:1043003 +MSDTGSPPQKPEGGEHLNIKVTDNNNEVYFKIKRTTQLKKLMDAFCERQGKAPTSVRFLFDGQRVNPTDNPETLDMQDGD +TLEVHQEQIGGC +>A0A8C8GBS1|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:74940 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGLC +>A0A319EQ78|unreviewed|Ubiquitin-like domain-containing protein|taxID:1448318 +MADSGAPAGDAPAAVEHLNIKVTDNNNEVFFKIKRSTQLRKLMDAFCERQGRQASTVRFLFDGTRVRPEDTPDTLEMTDG +DTLEVHQEQIGG +>A0A1B9IMB2|unreviewed|Ubiquitin-like domain-containing protein|taxID:1331196 +MSDNGSPAAPPAEAKPKPEADPNTLNIKIVSTNGDEVFFKIKKTTKLNKLKSAYADRVGTDVAAIRLLFDGQRILDDQTA +NDLDLEDGDSIEVLLEQVGGY +>A0A452F2Y8|unreviewed|NFATC2-interacting protein|taxID:9925 +MAEPLRRPGRPRGGGGGRRVRGSRGGRSRCPGAQRSPARRTLDSVLVDLVSDSDEDVLEVATVPLPESPVPAVSRDDRDS +DSEGADAEPGGAPRVLVRRRRRLLLDPGEAPAVPVYSEKVQPGSREEADVEDASSPHTVDFPCPSSPWKKKLRSKDGEEK +KQMQEHWGRRSRTGIGRAQDTSPLPSPLPRTKSRKHTQALRKLREVNKRLQDLRSCLSPKQSQGQAHLSQEDEVVLVEGP +TFPEHPRLLPLKIRCRADLVRLPIRMSEPLKSVVDHMAAHLGVSPSRILLLLGETELSPTATPRTLKLGVADIIDCVVLA +SSPEAAETSPLLQLRVQGKEKHQTLEVSLPPDSPLKTLMSRYEEAMGLSGHKLSFFFDGTKLSGKELPADLGMESGDLIE +VWG +>A8MUA9|unreviewed|Ubiquitin-like domain-containing protein|taxID:9606 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQVRSWLR +VVPGRLPICAGWRWRTRTPSTCSSSRREVCRRAAWQGTVSRGPVPSPGRPSSHCC +>A0A8H8RRZ8|unreviewed|Ubiquitin-like domain-containing protein|taxID:215460 +MSTPGSPSSPAPELPAAAPVEDQKPKTQVIEVKAKDQNGSEVTFKIKRTTPLEKVMDAYCKNKGLAKDSLRFFYDGLRLT +GTDTPEKTFDMEDMGDDEVYQIDVMMEQHGGY +>H7BWX9|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:10090 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERVCQ +>A0A445JD38|unreviewed|Ubiquitin-like domain-containing protein|taxID:3848 +MATSRGRPPKRKSPDDNEATDNIQINFSIIDQDGRHMYFKVNHNLELIKVFKDFCERKNLEYETMQFLCDGIHIKGKHTP +KMLNMEDDAEIFAATHQVGGGGDMRC +>A0AAD6JBK9|unreviewed|Small ubiquitin-related modifier|taxID:889485 +MSASAGSGGGGGGGGGGGQEEDKKPGGDQSAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCARQSVEFNSIAFLFDGR +RLRGEQTPDELDMEDGDEIDAMLHQTGGGHASLD +>A0A8B8QL93|unreviewed|Small ubiquitin-related modifier|taxID:178133 +MSATGGGGSGQEEDKKPGDQAAHINLKVKGQDGNEVFFRIKRSTQLRKLMTAYCDRQSVELNSIAFLFDGRRLRGEQTPD +ELEMEDGDEIDAMLHQTGGY +>A0A9Q8PGZ2|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:5499 +MDSLPAHNPMKVLDRDPIVKADPGYVNICFASRSSSFALTFKVRKSHMFKDVKAAFGACTDQQPGGLVYTFKGQVVEDAN +TSEQLRLKNGDMVEVAAVGDADFTGACSEHRRVTELDRQGFQCISVMNAGESLVVKVRLLSGYTQPYCIKPNTQMSKLVA +DFEQQVGEQDLRFITFDGDHLHGRRNCTAENAEIEDGDTIDVFREQIGGGGTLIQKFEAFLRVPQRHGK +>A0AAJ0FSS6|unreviewed|Ubiquitin-2 like Rad60 SUMO-like-domain-containing protein|taxID:1093897 +MAEMASPTSASPAKKKKNLPFKRTIARRKSPDPFSDDRSPAKAASKAKDGEDDDDDGISMFRRSNEVFPLAIEEQQRRLK +REEKRRKAVPTERESPQKQDAKRRRVSGDLDSDDDGFSASGSRRRSQRNSTPRSTSEYVQAKIVSPIPGFRDIKKGVGDN +PTEIMRHAVSQSPRVLKSREASHPIIDIDDDDNIGVSATPNRMSWNKAIETTEPALTKEDDDDPLSDKSTPTQGEPNVEF +NEENDIAAADDPPDEFSKYVLQAREREARANSVQAPTSEAGDNTGKGQQSSKSSNPATRPTHPSIKIMVSSLLPNTAAML +AKLKLTQTLSVIRNAWINYQRHKATAMPEDVERQIFLTWKGNRIYNTVTCASLGLELDSMGKVRWDPYSEDESGYHSGGL +HFQAWTEELYAQYVKEKERERLRCLGELDEDEISSADGGLVDEQEEETEKLIRVILKAKDYKPLNTKVHMDTTVETMLTV +FRELRKIPPDKETALYFDGEKLDEATTVQEADIEDMDNLEVHIKEGLSVVADG +>A0A8C2UEX3|unreviewed|Small ubiquitin-related modifier|taxID:93934 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMED +EDTIDVFQQQTGGVY +>A0A812XFZ2|unreviewed|ABC transporter domain-containing protein|taxID:1628268 +MGAIFMAIMIPLYMGFAVQSALTCAIIEVVNEKESKMKVTQEIYGLTPLMYWVSWAGYFGIVSLVCMVALYCLFTLAAPV +VSNSNPLFVLFVMALSYMQQLEFAAIIAVFFNRTQAASSAANFFGFILLLAAVGLQGLLRGAPKILWYLAGLLPSVNVFN +GFAGLFWNEALYYCDAEGCTKGLIMRSLFATELCPVATYPDPCPAHIEIFSAGESMILMLVDVVLYAVVAWWLEQVWQGE +YGQAKPCFFCFDPAFMCPSRHRRNAGLLQEDGLESGREELAMSIKNMRKVFKGGKVAVDGMDLDIRRGEIFALLGHNGAG +KTTCMNCTWATPLNLMNFVLGVVGLIPMTSGSASVSGYDVHTRIEDVRRFFAGLRGISSQLQGAKVMEVLVALGSGDAPQ +HIQLKVKDQQGSEVQFKIKKTTPLRKLMDAYCSFMVDGERIAADDTAEKLGLEDEVATALLGETPLVFLDEPTSGMDPSS +RRQLWQLLLKMRSTGRSIIFTTHYLEEADVLADRFGLGYNLQVAFLPGAPAPEEAEALGSLIRKHVATATLRSPERSDEE +EHASKPKCRSNINKHIYVVFWVLGLVLGAAGAAVLVVLVRLVLVHWCAGAVLVLVVLLVLVALLGMGLGLGLGLGPGLVL +VLGWWSCSSGVLVLGLVGGPAAAACWCCWCCWRCWCRFW +>T1DPS0|unreviewed|Small ubiquitin-related modifier|taxID:42839 +MADEKKDNKGSESEHINLNXXXQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTTLEMEEGD +TIEVYQQQTGGGVFQEGGEITM +>A0A091XPD6|unreviewed|Small ubiquitin-related modifier|taxID:30419 +FLQEAKPSAEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRITDNHTPKELG +MEEEDVIEVYQEQTGGHSTV +>A0A1G4KF46|unreviewed|Ubiquitin-like domain-containing protein|taxID:1266666 +MSEPQQETKPDIKPETHINLKVSDGSSEIFFKIKRTTPLRRLMEAFAKRQGKEMDSLRFLYDGVRIQADQTPEDLEMEDN +DIIEAHREQIGGASL +>A0A5J4VCQ9|unreviewed|Ubiquitin-like domain-containing protein|taxID:222440 +MHLIIRDLNKDVFTVNVEGPEETIETVKLRIIACQDINYHELYLIYKNEVLEDERTLKSYNITQRCTLNLIVKEQEKPHH +QPDNNHVEIIVRSLYGEEIHVKMHKKTKIEKLINAVSEHFGIRQTQFHLLFEGYHVHQEDTCEKLEIQNGDVIEFMRTLV +AG +>A0A3P9MZS8|unreviewed|Small ubiquitin-related modifier|taxID:8081 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLIKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMED +EDTIDVFQQQTGGLI +>A0A7K9IFA5|unreviewed|Small ubiquitin-related modifier|taxID:381031 +QEGVKAEKEHIDLKVAGQDGSVVQFRIKRHTPLSKLMKAYCCRQGFTMRQVMFLFDGQPIKEADTPAQLELEDEDTIEVY +QQQTGGEC +>A0AAD6U1A1|unreviewed|Ubiquitin-like domain-containing protein|taxID:1033014 +MSQEPEDVKPKLNLRLIYDGNEITVKVKPNTKFTKIFQAAEQRFAKESGTFKFVYEGTRINKDDTPADLNIEDMDQIDCF +LEQLGGGFL +>A0A452VIG0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:29073 +MKAHCQRQGLSTRQIRFRFHGQPIHETDTPAEREMEDEDTPDVFQQQTGVY +>A0A5S6QUR4|unreviewed|SEC7 domain-containing protein|taxID:70415 +MEAEDGEVQKLDKSEEPDSAQERSIVIKVVNQHGQDVSFRVKSQTSMEKVKRTYALRMQLPLDSLRFQHDGRRITDDMTP +ESLKLQNNEAIEVYQGKSISLRLPSTRLPGASYHLALPIMGTSALYVVHSELNAVVTQLRRNQRVQTGISNSQDPFLRSF +IDLRDVLNSVSDLTDVAPSVFVSPFLDVIRSEQTCGAATGQALVAVEKFVSYGMFDPHCFTASSAVQQIAEAVTHARFVG +TDPSDDEVVLLRILQVLRVLLLSSSGPLLTDETVCEILQSCFRICFEERLSLLLRKAAESCLRDMVMVIFTRLSSFVEDP +RHPYVKRLIARGAAREERKHRKRKKWNYGQQQTSCLTTAGQIGSEKEMSVDSEMNVELTSKNDSTGNADHQPGDAVMDVH +SGTEASAENVLEVAKRPSGDQVTVADSVNVDVNLGRTNAEQLPSPSSDKSYPEDVSKMLDSPCSNAPYSAPHGIPCAREL +MRFLIALCNPWGQQNSDGIIELGLSLLLVAFEVGIEEIGRFTLLLPLVQNDLCRNLNSLLLTTKASLLSLTLRLGFLLFE +SLRVHLKLQLEMYLLRLMELAALTDVLPSPNNSAPSIRALAVSSNVRMELRELVLEALVALWRVPGFVTELYLNYDCDLY +CSSLFEELTKLLSKNAFPVTGLTGAHVLSLDALLTVIDTIEMNCHMRMISFKEKPICSDERRSTGNVSSKLHHCYATSNS +GITDSMVYAGSSELETVKAAGQKETMLQVPSLRRSRVLPSASIPSHEDLIALKTKKRILTAGSELFNQQPLKGITYLQEH +GLLETPYNLGALVQWLRENPRLNKRKIAEFIVNRKNKSILEAFVRSFDFRSVRLDDALRLFLESFRLPGEAAEISMIIEY +FADHWYNSNEKPFASTDAAFTLAYAVIMLNVDQHNPTAKKQQQPMSLEEFVKNLNGVNGGKNFDPSMLEKIYVSIRNEEI +VMPEEQSGIVRENYLWEVLLRRGSTDQGRFLHAPSGLYDHDLFSLVWGPTIAALSFVFDKTSEQDAVVARIISGFRKSAA +IAAHYSMCDVFDNLIISLCKFSTLMSIGMGAESNDHFCASFAASSKAQMAAKTMFHLVHSHGDILREGWKNILECLLHCY +HAQLLPRAMLQVEDFVDARGFVSIARRPTRPAKTDSSIFTSLYNYLGGGGSNDSRTSSNEAADCVCTTRAVLAECHPEQI +ISDSKYLSGEAFSELLKALLMASALVLTDIRQGTVLSEQAEFSLIFYTELTIAVALENRDRIGPFWRTLTTHLFSLMSDF +GEKRFLTERATVGLMRLAVRLLVRDEVRDDVLSSLRLLQSMKPASLLVMARQIAFGLHAILRNNAAHIKRQAHWSVLFSL +LETVGAAAFPSDWERCRDSSDEGIQSDEDRASMEVGRDDRGYTSDSEVYNVGKRTSLDEATNAARLGQRASSGEWLFVVK +KDAPFPVASMDATQQQRFSSNRLLLRSRLRSHDPQAYVKCCETLTFLVRDMAHITQENFDACVQCLRTFIEAGLNGGFHY +MDQSLDVLPAQNDNSRSSKSRGSKKNRGSADSNDKSERDSSSEAAEVGAVYLQLSLQLLDLTYLLFVQAAAVFGEESGDV +PFKADIWGRVWQPLLQAMARLCFDRRKVVRSTAVTLLQRSLLIPELRRLDGADWEKCFYNVFFPLLNALVENAESEDDTC +GNDETRVRALTMAGKVFLQHLMFLSALPSFVDLWMDILSFMERYLQLKSSDLSESVPESVKNMLLVMDTADLFHRVPTLL +ERTEQRLTGPFEALADTIGKRPSEEAGISSEESPPKASELDSTLEEVIVIDALPSQEIAKPAVNLVAYPNKDNVTTVEQQ +QQQPCSSSPAAVVLFGPRREHNAPVGNLVLLPPSQPSSVVQPLLFGPAVLTNTDVPTFDAK +>A0AA35L7S4|unreviewed|NFATC2-interacting protein|taxID:74358 +MAETVGPCSSSDSEPEGTPRKPPIKRRRILPADFGVAAVPVYSSKVQNSLHLFPESLKLPVQIPVLSSEPQVIDTSDEEE +AEEEEAPTKQVEQEKRRKALSPSPPPPPQLRKRRHGAKNFHQKLRNLTSSLSAAKKSLQDEELRDDVILIDVLEPSESQE +LVLKIRCRADLYKVSVQMTDPLQRVIEHMAQTLKVHQDRILLLLRDRELAADATPRVLGLGVADIIDCVVETTSQGSSDA +GNLQLRVQGKDKSSQMEFTLQRWEPLQKLMSHYRKAQGFGRCKLAFYFDGQRLAGTCTPEELGMESGDVIEVWS +>A0A8S9BW30|unreviewed|Ubiquitin-like domain-containing protein|taxID:2728926 +MDDPFENDAPEAAAPPPKKRSLFSSATIAKSNAAEEAVEFFSRAKELHPQMLAQEERRRQKRLLKLERKRSSTSADTKEI +TPPEEKRRRVSAQAKSHDTYSSDESQNHDIDDSSRTRRQSSHSSPGSRRSRHGSDPHVAQASGTTLSASYNREINARKQQ +LPKPGISTGCITLSDSESDSAKTTLPVRKPAKQHITLIDSDDDLSPLRKPTKPIVEDDNQFSDEEFPEIVAAAKERARKK +AEEAARLSKAFAEQNHAQNGDRTQDLDDIFDTASGLADADPSVEILITSVMAGTNPLRVKRRISQKLAEVRHAWCDRQSF +EGQPMGPDFKDQVFLTWKNIRVFDYTTCKGLGLKVDGLGNLVSGGDSIDPDGRVHLEAWTEDAFAIYQKRQEAKKKKAQG +HDNSDGLEEQKEPPVKRTKLVLKSKDLPEYKLMVKPSTTVQRMIEAFKDANSIPDEKTVTLHFDGDKLELSDTVEDTELG +DMDTVEVHIR +>A0A6P8T6X7|unreviewed|Small ubiquitin-related modifier|taxID:8218 +MADEKPKEGVKTENNEHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPSQLEMED +EDTIDVFQQQTGGFSL +>A0A8B7DZN0|unreviewed|Ubiquitin-like domain-containing protein|taxID:6087 +MEKDSNEEADSDEEILNYGSKKLLTFLHNEVVMNFSSSEDDDVSKTSEDESEKSLDSSLFNDTSLVNDEKNSIRFNSVLS +PSPPPPPLKHARLDVLKSSEVLQRLRKECVVASTPDDQIWEKKCEDLCQIKVRLHGEVKKFFIKKNEPFLKIIEQIAKQE +KVPITCVVLNNKLTTIDVNDSVQKLNITICDIIECMIYENNEELDKITISIQAESNTKRKSKIDFKISPIEKLSDIFSTY +CESNHVNIKTTSFTFDGDKIDPNKTAIDIGIEDGDVIDVIFN +>A0A8H7XPK0|unreviewed|Ubiquitin-like domain-containing protein|taxID:181762 +MSEEDHQANTQEHELKQEDANATINIKVRRHSRKKRDFGEIIEWLIDVVNSQVVSSSGEEVFFKIKRSTRLSKLQGAYAS +KVGKDVGSIRFLYDGSRIQEDDTPATLDMEDNDTIDVMVEQVGGSLAALP +>A0A8D1IV28|unreviewed|Ubiquitin-like domain-containing protein|taxID:9823 +MSDQEAKPSTEDLGDKKEGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYCQRQGVPMNSLRFLFEGQRIADNHTPKEV +SIISSLNQDRFKICIQRFGSLVLNCPFLGYSPDLSGISFVRKIIFFFFLVFLGPQHMEVPRLEVKSEQQLPA +>A0A6I9UMQ8|unreviewed|Ubiquitin-like domain-containing protein|taxID:4182 +MRPGETSNGKKPNHDQSIVSKIALSIKSQDGDEVYYRFPRDKKLQYLFTSYCKQKKLNYDAIAFVYDGQRVKASKTPLEM +EMEDGDSIDAMMHQDGGGYALVMT +>A0A7N5JW30|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9646 +ASSLLIPTEDQLEAILIKLHHRRTIQPRPEPGAPPRRAGCACPRLFPPAWRAPGPGRGGARRGXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXGRPRAHRPRAELLGPGRARVRRGVR +ARGVPTLRGPRAGPRRVLPPPRWRGVPSASGFPFRDGGLRASRVPCPAPRWPGEGSRRINGLPMGSPSGRCEGPGVRGIP +GSISRFPGFGVSRGLGRGFSLGARSPLTCGDHAVSRSWRQRCEQKDLEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPL +SKLMKAYCERQLEMEDEDTIDVFQQQTGGVY +>G0RDH1|unreviewed|Ubiquitin-like domain-containing protein|taxID:431241 +MSDEVAAAPVRKKKLPFKPTALRNVAPVSKPATTAEDGKKGEGDDDGDGLDLFRQSREMERIVAAERERKLNKKKQKQAE +EERHLSDMAEKQLLESDEQHHEENTAVLTLKSSAGFEDAQATPVDDSLALEGDGFSRELVTPPPSKRSRRDSDQGSKSSK +RRRSAAEPLEDDPFHATPSGAPLIDLDSASESESDFDDDGVDAEEKDVGTAAPPSAQQREDSVEFVGSGTLSGDILSPTP +RAQTTTEMEEDDDEFVEYVRKAEAQRARDKDMMQLDSEKTVEKAAAAQIMVQSSIPGTKPACIKYLFNKPLRLIRDSWIA +LQRRKGVQLPITSDNDIVLTWQQKRVYTNSTLLSLGIRPQGDGKIIADEYSKGGLLEGRTKVALEAWTAEGFRQWEDEEE +MRLRREAGELPEEEPTQEPEGKRKKLRIKLVAKGMDVVKLSVLPETTVETLVIGFQTQRSVASDKDVSIWFDGERLEEHQ +TMEDAGIDEMDTLEVHIK +>A0A8H6WVQ8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1325293 +MADDQPSQEEVKEENGTINIKVVSQAGEEVFFKIKKSTKLSKLQGAYANKVGKDVQSIRFLYDGQRITDDETPASLEMEE +GDTIDVMVEQVGGAGAAARP +>A0A6A5RLD8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1150837 +MSDNGSPAQKPEDAGPSEHLNIKVTDNNNEVFFKIKRTTQLGKLMNAFCDRQGKNISSVRFLFEGTRVGPTDNPDILDMQ +DGDTLEVHQEQIGGSW +>A0A6J2TW81|unreviewed|Small ubiquitin-related modifier|taxID:7225 +MSEEKKAETEHINLKVLGQDNAVVQFKIKKHTPLRKLMNAYCDRAGLSMQVVRFRFDGQPINENDTPTSLEMEEGDTIEV +YQQQTGGDMGNSSQNA +>A0AAE0MN91|unreviewed|Ubiquitin-like domain-containing protein|taxID:314031 +MAENAENGSPQQPEAPGAPEHLNIKVTDNNNEVFFKIKRSTKLEKLMTAFCERQGKTLASVRFLFEGQRVQPADTPDTLE +MQDGDTLEVHQEQVGGW +>A0A818N7V2|unreviewed|RING-type domain-containing protein|taxID:433720 +MANLYQIENLLRCSICLNRFQIPKVLECQHTFCYTCLQNIYDSENQILICPICQRTIKLTEGTDELPDNILLINLMKIQP +IKGKCSSCQKIDTLTICEYCQCTKCIDCNEKHVNDMRKLLEIKLNELEKTNQNEFKVPVHNYVKIKRNEINNQFQLIRQE +HHSNLFQKQMHILEQLESQEQILLTQIENDFQLLEQIKLDIINRNIDINSKTESELLNVLRKASDIQKCLTEKLTQYHLY +SCEIILQYDEDQTNAINHLCDSLQLNISDRNSVSSEFINITLRTFLNQEYQYRISLDKTIYELKEIFSKQVNLDPKKILL +TKFDNYTDELEDNRTLKSYEFNSTSILMVCLRK +>A0A4X2L599|unreviewed|Small ubiquitin-related modifier|taxID:29139 +MADERPKEGVKTENNDHINLKVAAQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDEQPINETDTPAQLEMEN +EDTIDVFQQQTGGAY +>A0A642UDC0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:44093 +MSEDVGKKKVSKWKTKRKLTPAKYVPPEPTGAKDDSFFRLAGPGESTAENDDASKPQTTTIREEVEVIDILDPDYEEKMA +EQNKRRKTQTPDQESSVAEDKNDAETDVQQPQPADDGVAVVAVDVDEEEEEEGEEEDATVVSSRERDPLSGVLSEDMDAA +MLERIRRKREAARHQSAFPVSVEVKVEIRGLGGFGRGFDMQSNERFRDVRRRLLEHVATGGIASGSASYRAVQEGYFMHE +SVRVFDSSSPMSLNISRYTPTMQVSLMTPEDFEARQRAVEEEYARKREQALQEQRERERQEREDEERAARAAADAAEEEE +GEAGDAADAAAAGDDGFFTVYMKGKDNEAVGVQVNAETEIKKLAAYYKKKKGLPDNAEIRLEFDDEDLPADGVVGDTELE +EDYSIDVYVS +>A0A4Q4MK64|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:119927 +MTDSTASAAPPKKRSLFKRAAWQDAPKKDSEDMFSHSNEFKDIVAEQARTRAEEKKKAEAARKRKHSEPRDQKRRRISND +SEELVPLKNGSASKERVGRTAAKARSITSVSPAPSRPPPDSLTARYDSLTKSASSSISLPQKESHVIDLGDSDEDDDDGY +VSKPVNDNPAIDYKSPASDFRQDIAVRPSKPPPIEIKDDDDDDDDDEDGDPAFAALRARARARVAAAKAQANGDAPKAPI +VQLLIDPQMPDAKPLMVKVRVDSTIGKPRLAWCGKEKFSEQMTRSVFFTWKGTRLYDSTSIKRLGIQVDDSGNVSVQGDS +NIYDDVNLPKIHVEAWTEDVYKQRKKEDAAAALAKKLAAEAAVVTREKTPTPEPEPEPEEKRFRLVLKAKGYSDFKLTVK +ESTTVAHIASAYKTRHKIDKNQPVTLMFDGDRMMPLDTVADYDVDEEETCMIEVLLK +>A0A3Q7TAW0|unreviewed|Small ubiquitin-related modifier|taxID:9627 +MADERPKEGVKTENNDDINLKVEGQDGSGMQFKIKRHTPLRKLMKAYGERQGLPMRQIRFRVDGQPINEPDTPAQWDVEG +EETIDVFRQQTGGVY +>A0A1Y2W1R4|unreviewed|Ubiquitin-like domain-containing protein|taxID:1001833 +MSGENDSGSPAAERQEAPAGGSEHLNIKVTDNNNEVFFKIKRSTKLEKLMTAFCERQGKSVEAVRFLFEGQRVQKGDTPD +SLEMADGDTLEVHQEQVGGACRR +>B0XQK4|unreviewed|Ubiquitin-like domain-containing protein|taxID:451804 +MADNGTPSEAPAPPPVEHLNIKVTDNNNEVFFKIKRTTQLKKLMDAFCERQGKQLSTVRFLFDGTRVRPEDTPDSLDMAD +GDTLEVHQEQIGG +>A0A340XEG1|unreviewed|Small ubiquitin-related modifier|taxID:118797 +MSDPEAKPSTEDLGDKKEGENTKLKVIRQDSSEIHCKVKMMMHHKNLKESYCQRQGVPMNSLRFLFEGQRIADTHTPKEL +EMEEEDVIEVYQKQTGAFNGFPEDCHRMCNKQQGPRL +>A0A671KP06|unreviewed|Small ubiquitin-related modifier|taxID:1608454 +MSVFEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSIRQIRFRFDGQPINETDTPAQLEMEDEDTI +DVFQQQTGGSC +>A0A1Y2FU55|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:2754530 +MAFSDIDEDAAFFSHAQPIILGKRKRATKPGDAAPTPEILALSSESSESSASEAEEHRPPVLKKGGLTNGKENAIAREAG +SPSGSSPIKQDNYFEISSDDATEQPGGRARANNGKKKKVTQAEQKHRRMSLTPPPEPSGTAKLRAAERAAQARRAQRHRS +PDVSVQTNSPPELMTKSAAELAFEKEVAQRVRSREALTRSGMGSYSLSRLQEDHDDEEAPIEVLVRGVYVQLPEEANQSH +RAGFQLPDPKKWEQMQRFKLKRSTPLRIAKVHFCGQCNITDQQAEQHIVMAYGSVQLFRSISCAALGFHANEKAMPLFDL +YTRQGWQYVCDNPEAAKALREQSARLLNPDAHKEDGDSAQSGENGEAEEEEGRGHIVLILRGKGNVQLKIKTTASTLVKK +LVEAWRQKEKLAADVKIRLMVEGDALSPNTMIGDADVETGDTVDVQVG +>F4SAB4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:747676 +MEFLEIMILESQSRIRFKVIGYEGNLVEIKMKRTTRFDRVMDVYAEHTGLKNGTFCFRWDNQRLCGESSPEDLRMTDGDH +VEVVITWDTCAVCAARNPQTIS +>A0A8D2ZGX8|unreviewed|Small ubiquitin-related modifier|taxID:52904 +MRESRQDGGDKKDGEYIKLKVIGQDSSEIHFKVKMTTHLKKLKESYSQRQGVPASTLRFLFEGQRIADNQTPKELGMEDE +DVIEVYQEQTGGLWND +>J3K9Y5|unreviewed|Ubiquitin-like domain-containing protein|taxID:246410 +MRSFFKKPTWANADTEAPLTEFYRRSQHLYSDIVAEQQHNAESDHEEEKQPNPVTDEELRGERHVKRQCTSSNNTVTVSS +CPVPKPTSFTVNGRQTNPVDLDIATKPLECTTTVEQLLPEPVSETSNDESLSEEEFPELARKARERARQHVAFSSGHAPA +MQKPDLHKARNEFNAESPDPIVPGLHCKTGEAPLCDPVVQILITSSIENTKPLLVRRRLSQNLGDVRKAWCNKQAFSPKL +AFSIFLTWKGRRVFDVTTCQSLGIRAPAASDSSFFANSFSNDDGMLRIHMEATTQELVEMQKRQGYMSLHQAERSSIARE +EITEQVIRITLRTPSSEDFKLKVRPTSKISDVIKTFRTALEISEKVVDLHFDGERLNPDSSVRDNDIDDLDCIDVVIKNC +R +>A0AAD6FL77|unreviewed|Ubiquitin-like domain-containing protein|taxID:1090488 +MMDSRICLAAVLLLFGLATVFAQSSPDQVSVVYHIQVVCNVSSDDHPSTTCTLSSERSTLGALLDELPDVDNHLVSVWCN +SHHRPHDLPVLLLQVSELWEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCDRQGLAIRQIRFRFDGQPINE +TDTPAQLEMEDEDTIDVFQQQTGGHC +>A0A2Y9FJ40|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:9755 +MADEKPKERIKTENNDCINLKVAGQDGSMVQFNIKRHTPFSKLMKAYCERQDTPAQLEVEDEDAIDVFQQQTGGVY +>A0A329SHV8|unreviewed|Ubiquitin-like domain-containing protein|taxID:29920 +MSSDEEEVKLYSALERNKKRQMMASYTVRNTPSNPNFLLVLFAVSLSSSSDEGDDDGDFDGFTILETPSKRRRQSASPAQ +AKSPARAARKLLNDSDEDDDDLYTPKEREAERLRKLRLEQEIRQKLEKDKVLNQTRAILNKVSTTKRQTTVNNLEVISLD +SDSDDESDEVAPVVPVAPPPQPVVDKGPRITLHIRSNGGAVDEIGIHKKETFDHLYTSFCELHGLPRSAIKMSLDGDALP +LMGTPASEDLDTGDIVEAKVDFSKQNEANKKKYLRLRLVVFGKRSEVFKIDSTATVAKLHGSYCQKHGITNPDDVVMSIQ +DQKLQLNEKLNLYGLIDNDEISVKVNNYVAPQPQSRTIDLQLRFSEGDPVTHQVVPTSKVEALLVKIANEKQCEVSNISL +MIDGEKMAASQTFHDYDLEGGELVEVKIVC +>A0A3P6A8W6|unreviewed|Small ubiquitin-related modifier|taxID:3712 +MVDSFSISSGSFETKKSPPLDQKRKEKKSPPPESSSQKKIMIKVKSQQDGGEDLYKIGENAPLKKLMTAYCVKKNLDRST +VRFIFKKKGLKPRHTPSQLKMEDNDIIDIVTEQGGGGPYTA +>E6ZKN9|unreviewed|Ubiquitin-like domain-containing protein|taxID:999809 +MDDVAFFTRKPVASKSKSKPKAKATAKVVNGSASNGAAHPTSSATVASTSQSAATAREDDPDAAIDVDALEDEEEDQDED +EDTLMSSSDFDISSDDSDASAKRRAKRRKKRHAKTLPAWASQGVYRRPSQEPSSSSSNSVFLDAPSGATASSNQLGSDKT +ADTGSPSAKPNGKAANGRPRRVSLTPPPPPSPEKLYMARELVNRTIASKFGTSAAASTTTASSSTAPVLSSSNDSASGSR +RPTRSTRNSATPAFGQDVANAGPSTALSPTAATRRHSGVDDDDDDDDEIDQIHWDPDLARLMRGDNAKHIREQARREQQQ +REERRKQRELERLRQQPSLQRSTQFARTQSAPQTTTTQARASAANGGNESDDSVEYVARPARKTSTSPRRIRSTTNTTTA +AASQYNKDAIIVIDDDDDEDGGHVSSSRTNGTAAAAATYEPSPSPPPAQEAAGETLALTLQSKLGSIPVTVTPATLLSRI +IQHFHEKKLDASVKVETVRVMFDGFAYKPNQTVGDMDVEDGDQVELSWP +>A0A8C0U905|unreviewed|Ubiquitin-like domain-containing protein|taxID:156563 +MKVYCCRQGLSMRHIMFLFDGQPIKEEDTPAQLEMEHEDTIEVYQQQTGGGC +>A0A507E9G4|unreviewed|Ubiquitin-like domain-containing protein|taxID:117820 +MHDRKRRKYTSPAPLENFTETIISDSDDDTSHCQTKDRLQPSARRPPTGRHRSVPSRSSNEKDFTSFFDMDGGTALCSIE +TKKATKATRQASRSPTPNDDDPQALWRGIPQRRNRSLGSKVDMASKHQKKRRQVDVTSPIAESNLPSICVNEKQTAAVGE +ITVPSDREPSLTPPPQLPHQDSNVLNTMSQMLEKISEQLQPTYLPEEPQISTTMLDPVLQNLGTGVPPEGGDQVITVKVK +FKPWPVREGCPKPLAYKLLMQFLKYTQSQSFEVLMRVTCTKWNVSDMRDMIFVYEGTPLFPRGTPASVKMDGKPIIEAYI +RSEYDALRRAQESEQKPVHEDHNVGGDAEKEGNPCNELILLKMQDSTEITKIKAKKGTTVEALIAAYQKLRSISHGTCRL +MLDGEVLDSSMRLEQLGLEDGDLLEVQ +>B5XFS0|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:8030 +MADEKPKEGVKTENNDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQLEMEDEDTIDVFQQQTGGLY +>A0A8T3C764|unreviewed|Small ubiquitin-related modifier|taxID:94219 +MASTSSKKNKKSNEVTILCLKVKSQDGEELVYRAKPTTKLSKLKNDYCNRHSLPINSIAFLFDGRRIHDEDTPESLKMED +GDEIDAMIHQTGG +>I2CYB9|unreviewed|Small ubiquitin-related modifier|taxID:9544 +MSEEKPKEGVKTENDHINLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSMRQIRFRFDGQPINETDTPAQLEMEDE +DTIDVFQQQTGGVPESSLAGHGF +>A0A8C9LQR0|unreviewed|NFATC2-interacting protein|taxID:591936 +MRKSEPLQSVVDHMATHLGVSPSRILLLFGETELSPTATPRTLKLGVADIIDCVVLASSPEATETSQQLQLRVQGKEKHQ +TLEVSLSRDSPLKTLMSHYEEAMGLSGRKLSFFFDGTKLSGRELPADLGMESGDLIEVWG +>A0A8X8XVM7|unreviewed|Ubiquitin-like domain-containing protein|taxID:180675 +MSTVEDDKKPTDSTIHINLKVKGQDGNEVFFRIKRSTQLKKLMNAYCDRQSVEFSSIAFLFDGRRLRPEQTPDELEMEDG +DEVDAMLHQTGGA +>A0A5C3ETK4|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:86804 +MDYFRHLTLGNARREQEQEVREESPISEIEDLRDEIAIDANIKTVLEAAEEMSLRAWGDEGVVGVQGDVGDGSIGQVCVG +GDGAKAQVGVEGMEGERWKVAGDVGEEDREVENVGTANAGRSQGQEKKEWPMNECNDDEDSPLSRRHEREQQPSQEPFSV +STATTTVANNNNIPEAATNSNAITFNQNTEDVEMAEANNAQQSHPYILLPITTSSPPPSTPPLPPHITLSLRDANGYDTC +FRCRPTTKLSKIFKAYADRYQASVGNIRFISQHGNLLPEDDSFATVQNMGLEDGDEIE +>A0A1M3TBL8|unreviewed|Ubiquitin-like domain-containing protein|taxID:1137211 +MRSFFKKPSWASRGDEGTDPNFYRHAGQVYNDIITANRKARASRLSVVQEPKEEQKEEPEQEPKQESEQESEHTNSKRRR +LSCRQPSAESSLGALTHNEALHNAEQPLDYDASYEHLQETNNNGDSCGPSAGVSTRGITVGITTETDDQCCESLPDVELT +QVGAIRAHSEVTKAVKENKIASVQQSRFQNAREVDEAVRPHNHSLAHNQAIVQILITSKIPNTKPLIVRRKMNQPLKDVR +LAWCNRQKFTKEMQESVFLTWKGKRLFDVTTCRSLGIHAKSGNFNGHDTFYLDVEDIQVHMEASTEDLLNADLSHSQTVT +DAKSSPEYTSWNGATSSPDRILLKCPGFGDLKVELNLEMQVSELVATFRVARQIPATRDIQLVFDGDRLDDNAYLADYEL +MDSDLVEVIIK +>A0A366QUP6|unreviewed|Ubiquitin-like domain-containing protein|taxID:231269 +MKKLPFKPTALRKAAPKPSQPEEAKESDDDGLALFRRRKEMAPIMAADLERRLKKRRAAEEEEERRRLQITGEKRTRDDS +EDAKDSEIPSQGEPSNAHEGPSSAQLNNETPIAEPASTQDGHDQTRFASLLHNLGPPSDQASELVTPPPSKRSRLDSNST +QKPMLSAQLDDDDEHDPFPDASPTPRARPQPSSPSPIRSRRPEPTSAQNQVVQSITIDSDSDDEVRPTQPIKRRSSSIEA +STKFLKETTPPVVAEEDDEFAEYIRKAQENRARQQALQSPDTNASPKKESISVMITSSIPNSGTLVARFLFDKQLRVARN +AWVSHQRKKGLQLNADDIILTWRRTKIYNTSTLNGLGIRPCGNGRVEADGLGSAGFSNNRSVVHIEAWTPELFQEMEQNE +ELQRRRDAGELSDEEEPQQEERERFIITLKARDIQPLECKVMPETTVDTLIAVFRKQRQIGPDKEVSLWWDGDRLEEHIE +MEQAEIEEHDTIEVHVQ +>A0A5J5N0S4|unreviewed|Ubiquitin-like domain-containing protein|taxID:9886 +MTTHLKRLKEPYCQRQGVPRNSRRFLFEGQRIADNHTPKELGMEEEDVIEVYQEQTGGDSMV +>A0A3Q3EVJ5|unreviewed|NFATC2-interacting protein|taxID:37003 +MRIFDPNPSPGSDLSVILKVPPPRLLLLKNDEELPTNSTVGELGLGIADIIECVVMAAEDESVSSIITVKLQSKDRDSSL +EFSIHREAPLSSVFSRYLSNVSAGAQRRVRFHFDGFKVTGDQTPAQLDMEDGDIIEVWT +>A0A6P5LDV5|unreviewed|Rad60/SUMO-like domain-containing protein|taxID:38626 +MTNEKPKEGVKTENNDHINLKVAGQDSLVVQFKIKRHTPLSKLMKAYTPAQLEMEDEVTIDVFQQQTGDTY +>A0A2U1MNS9|unreviewed|Ubiquitin-like domain-containing protein|taxID:35608 +MDPHALVVKQEPISPTKGSYINLKVASNLNELDPFFRVKRDDPLQQLFIKWSHRANVDYRTIRFLYDGKRVDGTRTPNQM +GLEDGDCIDAMTEQIGGHTMI diff --git a/tests/test_dca_frustratometer.py b/tests/test_dca_frustratometer.py index 720dee88..db13da7f 100644 --- a/tests/test_dca_frustratometer.py +++ b/tests/test_dca_frustratometer.py @@ -145,7 +145,7 @@ def test_create_potts_model_from_aligment(): except ImportError: pytest.skip('pydca module not installed') - filtered_file=data_path/'PF09696.12_gaps_filtered.fasta' + filtered_file=data_path/'PF09696.12_gaps_filtered_small.fasta' potts_model = frustratometer.dca.pydca.plmdca(str(filtered_file)) assert 'h' in potts_model.keys() assert 'J' in potts_model.keys() @@ -467,41 +467,51 @@ def test_from_potts_model_file(): assert model.potts_model["J"].shape==(len(filtered_aligned_sequence),len(filtered_aligned_sequence),21,21) assert model.potts_model["h"].shape==(len(filtered_aligned_sequence),21) +@pytest.mark.network +def test_download_and_filter_pfam_alignment_PF11976(): + """Test downloading a PFAM alignment and filtering it (no DCA computation).""" + alignment_output_file_name=f"{output_path}/PF11976_test_alignment.sto" + filtered_alignment_output_file_name=f"{output_path}/PF11976_test_filtered_alignment.sto" + + alignment_file = frustratometer.pfam.download_aligment('PF11976', alignment_output_file_name) + filtered_file = frustratometer.filter.filter_alignment(str(alignment_file), filtered_alignment_output_file_name) + + assert Path(filtered_file).exists() + filtered_alignment = Bio.AlignIO.read(filtered_file, 'fasta') + # The filtered alignment length depends on the current PFAM release; + # just check it's in a reasonable range for PF11976 (~67-80 columns). + L = filtered_alignment.get_alignment_length() + assert 60 <= L <= 90, f"Unexpected filtered alignment length: {L}" + @pytest.mark.skipif(not _HAS_PYDCA, reason="pyDCA is not installed") -def test_from_pfam_alignment_mfDCA_calculation(): +def test_pfam_alignment_mfDCA_calculation(): + """Test mfDCA computation using a small pre-filtered alignment subset.""" pdb_file = f'{data_path}/6JXX_A.pdb' chain = 'A' - distance_matrix_method='CB' - alignment_output_file_name=f"{output_path}/PF11976_test_alignment.sto" - filtered_alignment_output_file_name=f"{output_path}/PF11976_test_filtered_alignment.sto" - PFAM_ID="PF11976" - DCA_format="mfDCA" - - filtered_aligned_sequence="INLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSM-RQIRFRFDGQPINETDTPAQLEMEDEDTIDV--" - structure=frustratometer.Structure(pdb_file,chain,distance_matrix_method=distance_matrix_method) - model = frustratometer.DCA.from_pfam_alignment(structure, alignment_output_file_name=alignment_output_file_name,filtered_alignment_output_file_name=filtered_alignment_output_file_name,PFAM_ID=PFAM_ID,distance_cutoff=16,sequence_cutoff=1,DCA_format=DCA_format) + structure=frustratometer.Structure(pdb_file,chain,distance_matrix_method='CB') + filtered_file = data_path / 'PF11976_test_filtered_alignment_small.sto' + potts_model = frustratometer.dca.pydca.mfdca(str(filtered_file)) + model = frustratometer.DCA.from_pottsmodel(structure, potts_model, distance_cutoff=16, sequence_cutoff=1) - assert model.potts_model["J"].shape==(len(filtered_aligned_sequence),len(filtered_aligned_sequence),21,21) - assert model.potts_model["h"].shape==(len(filtered_aligned_sequence),21) + L = len(structure.sequence) + assert model.potts_model["J"].shape==(L,L,21,21) + assert model.potts_model["h"].shape==(L,21) @pytest.mark.skipif(not _HAS_PYDCA, reason="pyDCA is not installed") -def test_from_pfam_alignment_plmDCA_calculation(): +def test_pfam_alignment_plmDCA_calculation(): + """Test plmDCA computation using a small pre-filtered alignment subset.""" pdb_file = f'{data_path}/6JXX_A.pdb' chain = 'A' - distance_matrix_method='CB' - alignment_output_file_name=f"{output_path}/PF11976_test_alignment.sto" - filtered_alignment_output_file_name=f"{output_path}/PF11976_test_filtered_alignment.sto" - PFAM_ID="PF11976" - DCA_format="plmDCA" - - filtered_aligned_sequence="INLKVAGQDGSVVQFKIKRHTPLSKLMKAYCERQGLSM-RQIRFRFDGQPINETDTPAQLEMEDEDTIDV--" - structure=frustratometer.Structure(pdb_file,chain,distance_matrix_method=distance_matrix_method) - model = frustratometer.DCA.from_pfam_alignment(structure, alignment_output_file_name=alignment_output_file_name,filtered_alignment_output_file_name=filtered_alignment_output_file_name,PFAM_ID=PFAM_ID,distance_cutoff=16,sequence_cutoff=1,DCA_format=DCA_format) + structure=frustratometer.Structure(pdb_file,chain,distance_matrix_method='CB') + filtered_file = data_path / 'PF11976_test_filtered_alignment_small.sto' + potts_model = frustratometer.dca.pydca.plmdca(str(filtered_file)) + model = frustratometer.DCA.from_pottsmodel(structure, potts_model, distance_cutoff=16, sequence_cutoff=1) - assert model.potts_model["J"].shape==(len(filtered_aligned_sequence),len(filtered_aligned_sequence),21,21) - assert model.potts_model["h"].shape==(len(filtered_aligned_sequence),21) + L = len(structure.sequence) + assert model.potts_model["J"].shape==(L,L,21,21) + assert model.potts_model["h"].shape==(L,21) @pytest.mark.skipif(not _HAS_PYDCA, reason="pyDCA is not installed") def test_from_hmmer_alignment_plmDCA_calculation(): @@ -510,7 +520,7 @@ def test_from_hmmer_alignment_plmDCA_calculation(): distance_matrix_method='CB' alignment_output_file_name=f"{output_path}/PF11976_test_alignment.sto" filtered_alignment_output_file_name=f"{output_path}/PF11976_test_filtered_alignment.sto" - query_sequence_database_file=f"{data_path}/protein-matching-PF11976.fasta" + query_sequence_database_file=f"{data_path}/protein-matching-PF11976_small.fasta" DCA_format="plmDCA" structure=frustratometer.Structure(pdb_file,chain,distance_matrix_method=distance_matrix_method) From 46dbee7557b3c694b8cb2b70f1a8e189cd9aa2bf Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Wed, 8 Apr 2026 23:11:46 -0500 Subject: [PATCH 15/28] Fixes numba in sparse native energy --- frustratometer/optimization/optimization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frustratometer/optimization/optimization.py b/frustratometer/optimization/optimization.py index 181ab6ff..d71ef42b 100644 --- a/frustratometer/optimization/optimization.py +++ b/frustratometer/optimization/optimization.py @@ -696,7 +696,7 @@ def denergy_mutation(seq_index, pos, aa): self.compute_denergy_mutation = denergy_mutation if self._is_sparse: - awsem_energy = AwsemEnergySparse(model=self.model, alphabet=self.alphabet).compute_energy + awsem_energy = AwsemEnergySparse(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function else: awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function @@ -884,7 +884,7 @@ def denergy_mutation(seq_index, pos, aa): self.compute_denergy_mutation = denergy_mutation if self._is_sparse: - awsem_energy = AwsemEnergySparse(model=self.model, alphabet=self.alphabet).compute_energy + awsem_energy = AwsemEnergySparse(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function else: awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function @@ -961,7 +961,7 @@ def initialize_functions(self): region_means=compute_all_region_means(indicators1D,indicators2D) # indicator_means*=0 # Set indicator means to zero to check if the problem is with the mean phi or the inner product matrix if self._is_sparse: - awsem_energy = AwsemEnergySparse(model=self.model, alphabet=self.alphabet).compute_energy + awsem_energy = AwsemEnergySparse(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function else: awsem_energy = AwsemEnergy(use_numba=self.use_numba, model=self.model, alphabet=self.alphabet).energy_function From 63324581dfc1cc28e2a754ce93a688a5401359c5 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 13 Apr 2026 13:48:56 -0500 Subject: [PATCH 16/28] Adds sparse distance matrix pipeline --- devtools/profiling.py | 86 +++++ frustratometer/classes/AWSEM.py | 349 +++++++++++++++++--- frustratometer/classes/Frustratometer.py | 23 +- frustratometer/classes/Structure.py | 139 +++++++- frustratometer/frustration/__init__.py | 3 + frustratometer/frustration/frustration.py | 234 +++++++++++++ frustratometer/optimization/optimization.py | 15 +- frustratometer/pdb/__init__.py | 9 +- frustratometer/pdb/plotting.py | 186 +++++++++++ tests/test_awsem_frustratometer.py | 31 +- tests/test_sparse_distance.py | 8 +- tests/test_structure.py | 8 +- 12 files changed, 1009 insertions(+), 82 deletions(-) create mode 100644 devtools/profiling.py create mode 100644 frustratometer/pdb/plotting.py diff --git a/devtools/profiling.py b/devtools/profiling.py new file mode 100644 index 00000000..78b60196 --- /dev/null +++ b/devtools/profiling.py @@ -0,0 +1,86 @@ +""" +Simple profiling utilities for tracking memory usage and execution time. + +Usage: + from devtools.profiling import track_time, track_memory, profile + + # Context managers + with track_time("Building AWSEM model"): + model = frustratometer.AWSEM(structure) + + with track_memory("AWSEM sparse"): + model = frustratometer.AWSEM(structure, sparse=True) + + # Decorator + @profile + def my_function(): + ... +""" + +import time +import tracemalloc +import functools +from contextlib import contextmanager + + +@contextmanager +def track_time(label=""): + """Context manager that prints elapsed wall-clock time.""" + start = time.perf_counter() + yield + elapsed = time.perf_counter() - start + tag = f" [{label}]" if label else "" + print(f"Time{tag}: {elapsed:.4f} s") + + +@contextmanager +def track_memory(label=""): + """Context manager that prints peak memory allocated inside the block. + + Uses ``tracemalloc`` to measure only *new* Python allocations within the + block, so the numbers reflect the incremental cost of the code inside. + """ + tracemalloc.start() + snapshot_before = tracemalloc.take_snapshot() + yield + snapshot_after = tracemalloc.take_snapshot() + tracemalloc.stop() + stats = snapshot_after.compare_to(snapshot_before, "lineno") + total = sum(s.size_diff for s in stats if s.size_diff > 0) + tag = f" [{label}]" if label else "" + print(f"Memory{tag}: {_fmt_bytes(total)}") + + +@contextmanager +def track_peak_memory(label=""): + """Context manager that prints the peak memory usage (high-water mark).""" + tracemalloc.start() + yield + _, peak = tracemalloc.get_traced_memory() + tracemalloc.stop() + tag = f" [{label}]" if label else "" + print(f"Peak memory{tag}: {_fmt_bytes(peak)}") + + +def profile(func): + """Decorator that prints time and peak memory for a function call.""" + @functools.wraps(func) + def wrapper(*args, **kwargs): + tracemalloc.start() + start = time.perf_counter() + result = func(*args, **kwargs) + elapsed = time.perf_counter() - start + _, peak = tracemalloc.get_traced_memory() + tracemalloc.stop() + print(f"{func.__name__}: {elapsed:.4f} s, peak {_fmt_bytes(peak)}") + return result + return wrapper + + +def _fmt_bytes(n): + """Format byte count in human-readable units.""" + for unit in ("B", "KB", "MB", "GB"): + if abs(n) < 1024: + return f"{n:.2f} {unit}" + n /= 1024 + return f"{n:.2f} TB" diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index fddf876b..85f6ef6d 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -9,6 +9,7 @@ __all__ = ['AWSEM'] + class AWSEMParameters(BaseModel): model_config = ConfigDict(extra='ignore', arbitrary_types_allowed=True) """Default parameters for AWSEM energy calculations.""" @@ -54,7 +55,7 @@ class AWSEM(Frustratometer): aa_map_awsem_x, aa_map_awsem_y = np.meshgrid(aa_map_awsem_list, aa_map_awsem_list, indexing='ij') def __init__(self, - pdb_structure: object, + pdb_structure: Frustratometer.Structure, sequence: str =None, expose_indicator_functions: bool=False, sparse: bool=True, @@ -119,6 +120,32 @@ def __init__(self, self.distance_matrix=pdb_structure.distance_matrix self.full_pdb_distance_matrix=pdb_structure.full_pdb_distance_matrix self.chain_breaks=pdb_structure.chain_breaks + self._distance_is_sparse = pdb_structure._is_sparse + #Sparse matrices + self._sparse_distance_matrix = None + self._sparse_distance_matrix_elec = None + #Full matrices + self.distance_matrix = dense_dm + if self._distance_is_sparse: + self._sparse_distance_matrix = pdb_structure._sparse_distance_matrix + self._sparse_distance_matrix_elec = pdb_structure._sparse_distance_matrix_elec + if not sparse: + # Dense Potts model from sparse distances. + from frustratometer.pdb import distance as _pdb_dist + dense_dm = _pdb_dist.get_dense_distance_matrix( + pdb_file=pdb_structure.pdb_file, + chain=pdb_structure.chain, + method=pdb_structure.distance_matrix_method) + if pdb_structure.seq_selection is not None: + dense_dm = dense_dm[ + pdb_structure.init_index_shift:pdb_structure.fin_index_shift, + pdb_structure.init_index_shift:pdb_structure.fin_index_shift] + self.distance_matrix = dense_dm + self.full_pdb_distance_matrix = dense_dm + self._distance_is_sparse = False + else: + self._sparse_distance_matrix = None + self._sparse_distance_matrix_elec = None selection_CB = self.structure.select('name CB or (resname GLY IGL and name CA)') resid = selection_CB.getResindices() @@ -126,29 +153,160 @@ def __init__(self, self.N=len(self.resid) assert self.N == len(self.sequence), "The pdb is incomplete. Try setting 'repair_pdb=True' when constructing the Structure object." + self._decoy_fluctuation = {} + self.minimally_frustrated_threshold=.78 + + if self._distance_is_sparse: + self._init_from_sparse_distances(p, sparse, expose_indicator_functions, pdb_structure) + else: + self._init_from_dense_distances(p, sparse, expose_indicator_functions, pdb_structure) + + def _lookup_sparse_distances(self, ci, cj, dists, L, query_i, query_j): + """Look up distances at specific (i, j) positions from a sparse COO distance array. + + Equivalent to ``dense_matrix[query_i, query_j]`` but without materialising the + full L×L matrix. Each (row, col) pair is encoded as a single integer key + ``i * L + j``, the source keys are sorted once, and all query keys are resolved + in a single vectorised binary search. + + Parameters + ---------- + ci, cj : np.ndarray (N_stored,) + Row and column indices of all stored pairs in the sparse array. + dists : np.ndarray (N_stored,) + Distance values corresponding to each (ci, cj) pair. + L : int + Sequence length (used for the flat key encoding ``i * L + j``). + query_i, query_j : np.ndarray (N_query,) + Row and column indices of the pairs whose distances are requested. + + Returns + ------- + np.ndarray (N_query,) + Distances at the requested positions, in the same order as the queries. + + Notes + ----- + Every (query_i[k], query_j[k]) pair **must** exist in (ci, cj). If a query + pair is absent, ``np.searchsorted`` returns a wrong position and a silent + garbage value is returned — no bounds check is performed. This is safe in + practice because callers always pass indices that were produced by filtering + the same sparse source (e.g. the output of ``compute_mask_sparse``). + """ + src_key = ci.astype(np.int64) * L + cj.astype(np.int64) + qry_key = query_i.astype(np.int64) * L + query_j.astype(np.int64) + sort_idx = np.argsort(src_key) + pos = np.searchsorted(src_key, qry_key, sorter=sort_idx) + return dists[sort_idx[pos]] + + def _init_from_sparse_distances(self, p, sparse, expose, pdb_structure): + """Initialize AWSEM physics from sparse COO distance data (no L×L arrays).""" + dm_ci, dm_cj, dm_dists, dm_L = self._sparse_distance_matrix + + # --- Rho computation --- + if self.burial_in_context: + full_dm = self.full_pdb_distance_matrix + if isinstance(full_dm, tuple): + sel_ci, sel_cj, sel_dists, sel_L = full_dm + else: + # Full PDB is dense but selection is sparse — fallback to dense rho + sel_ci, sel_cj, sel_dists, sel_L = dm_ci, dm_cj, dm_dists, dm_L + else: + sel_ci, sel_cj, sel_dists, sel_L = dm_ci, dm_cj, dm_dists, dm_L + + # Rho sequence separation mask + rho_mi, rho_mj = frustration.compute_mask_sparse( + sel_ci, sel_cj, sel_dists, sel_L, + maximum_contact_distance=None, + minimum_sequence_separation=p.min_sequence_separation_rho, + chain_breaks=self.chain_breaks) + rho_dists = self._lookup_sparse_distances(sel_ci, sel_cj, sel_dists, sel_L, rho_mi, rho_mj) + + rho_vals = 0.25 * (1 + np.tanh(p.eta * (rho_dists - p.r_min))) * (1 + np.tanh(p.eta * (p.r_max - rho_dists))) + rho_r = np.bincount(rho_mi, weights=rho_vals, minlength=sel_L).astype(np.float64) + + # Handle burial_in_context substructure slicing + if sel_L != dm_L and self.burial_in_context: + self.init_index_shift = pdb_structure.init_index_shift + self.fin_index_shift = pdb_structure.fin_index_shift + rho_r = rho_r[self.init_index_shift:self.fin_index_shift] + + self.rho = None # No dense rho matrix in sparse mode + self.rho_r = rho_r + + # --- Contact mask --- + contact_ci, contact_cj = frustration.compute_mask_sparse( + dm_ci, dm_cj, dm_dists, dm_L, + maximum_contact_distance=p.distance_cutoff_contact, + minimum_sequence_separation=p.min_sequence_separation_contact, + chain_breaks=self.chain_breaks) + contact_dists = self._lookup_sparse_distances(dm_ci, dm_cj, dm_dists, dm_L, contact_ci, contact_cj) + + # Theta/thetaII at contacts only + theta_c = 0.25 * (1 + np.tanh(p.eta * (contact_dists - p.r_min))) * (1 + np.tanh(p.eta * (p.r_max - contact_dists))) + thetaII_c = 0.25 * (1 + np.tanh(p.eta * (contact_dists - p.r_minII))) * (1 + np.tanh(p.eta * (p.r_maxII - contact_dists))) + + # Sigma at contact positions (no L×L allocation) + sigma_water_c = 0.25 * (1 - np.tanh(p.eta_sigma * (rho_r[contact_ci] - p.rho_0))) * (1 - np.tanh(p.eta_sigma * (rho_r[contact_cj] - p.rho_0))) + sigma_protein_c = 1 - sigma_water_c + + # Store None for dense sigma (used in configurational frustration) + self._sigma_water = None + self._sigma_protein = None + + # --- Burial --- + rho_b = np.expand_dims(rho_r, 1) + burial_indicator = np.tanh(p.burial_kappa * (rho_b - p.burial_ro_min)) + np.tanh(p.burial_kappa * (p.burial_ro_max - rho_b)) + self._burial_indicator = burial_indicator + + h_index = np.meshgrid(range(self.N), range(self.q), indexing='ij', sparse=False) + burial_energy = 0.5 * p.k_contact * self.burial_gamma[h_index[1]] * burial_indicator[:, np.newaxis, :] + self.burial_energy = burial_energy + + # --- Main mask (sparse) --- + if p.k_electrostatics != 0: + self.sequence_cutoff = min(p.min_sequence_separation_electrostatics, p.min_sequence_separation_contact) + self.distance_cutoff = None + else: + self.sequence_cutoff = p.min_sequence_separation_contact + self.distance_cutoff = p.distance_cutoff_contact + mask_i, mask_j = frustration.compute_mask_sparse( + dm_ci, dm_cj, dm_dists, dm_L, + maximum_contact_distance=self.distance_cutoff, + minimum_sequence_separation=self.sequence_cutoff, + chain_breaks=self.chain_breaks) + self.mask = (mask_i, mask_j, dm_L) + + # Common properties + self.aa_freq = frustration.compute_aa_freq(self.sequence) + self.contact_freq = frustration.compute_contact_freq(self.sequence) + + # Build sparse Potts model (always sparse when distance is sparse) + self._build_sparse_from_contacts(p, contact_ci, contact_cj, theta_c, thetaII_c, + sigma_water_c, sigma_protein_c, burial_energy, expose) + + def _init_from_dense_distances(self, p, sparse, expose, pdb_structure): + """Initialize AWSEM physics from dense distance matrix (original path).""" if self.burial_in_context==True: selected_matrix=self.full_pdb_distance_matrix else: selected_matrix=self.distance_matrix - sequence_mask_rho = frustration.compute_mask(selected_matrix, - maximum_contact_distance=None, + sequence_mask_rho = frustration.compute_mask(selected_matrix, + maximum_contact_distance=None, minimum_sequence_separation = p.min_sequence_separation_rho, chain_breaks=self.chain_breaks) - sequence_mask_contact = frustration.compute_mask(self.distance_matrix, - maximum_contact_distance=p.distance_cutoff_contact, + sequence_mask_contact = frustration.compute_mask(self.distance_matrix, + maximum_contact_distance=p.distance_cutoff_contact, minimum_sequence_separation = p.min_sequence_separation_contact, chain_breaks=self.chain_breaks) - - self._decoy_fluctuation = {} - self.minimally_frustrated_threshold=.78 # Calculate rho - rho = 0.25 + rho = 0.25 rho *= (1 + np.tanh(p.eta * (selected_matrix- p.r_min))) rho *= (1 + np.tanh(p.eta * (p.r_max - selected_matrix))) rho *= sequence_mask_rho self.rho=rho - + #Calculate sigma water rho_r = (rho).sum(axis=1) if self.full_pdb_distance_matrix.shape!=self.distance_matrix.shape: @@ -191,9 +349,9 @@ def __init__(self, # Build Potts model if sparse: - self._build_sparse(p, sequence_mask_contact, theta, thetaII, burial_energy, expose_indicator_functions) + self._build_sparse(p, sequence_mask_contact, theta, thetaII, burial_energy, expose) else: - self._build_dense(p, sequence_mask_contact, theta, thetaII, burial_energy, expose_indicator_functions) + self._build_dense(p, sequence_mask_contact, theta, thetaII, burial_energy, expose) def _start_indicator_exposure(self, p): """Set up burial indicators and gamma arrays (common to sparse and dense).""" @@ -352,6 +510,134 @@ def _build_sparse(self, p, sequence_mask_contact, theta, thetaII, burial_energy, temp_gamma[:, 0] = 0 self.gamma_array.append(temp_gamma) + def _build_sparse_from_contacts(self, p, ci, cj, theta_c, thetaII_c, + sigma_water_c, sigma_protein_c, burial_energy, expose): + """Build sparse Potts model from pre-computed contact-level values (sparse distance path).""" + # Build J_sparse in AWSEM 20-letter alphabet: (N_c, q, q) + J_sparse_20 = p.k_contact * ( + self.direct_gamma[np.newaxis, :, :] * theta_c[:, np.newaxis, np.newaxis] + + self.water_gamma[np.newaxis, :, :] * (thetaII_c * sigma_water_c)[:, np.newaxis, np.newaxis] + + self.protein_gamma[np.newaxis, :, :] * (thetaII_c * sigma_protein_c)[:, np.newaxis, np.newaxis] + ) + + # Map to DCA 21-letter alphabet: (N_c, 21, 21) + J_sparse_21 = J_sparse_20[:, self.aa_map_awsem_x, self.aa_map_awsem_y] + J_sparse_21[:, 0, :] = 0 + J_sparse_21[:, :, 0] = 0 + + # Sparse Potts model + h = burial_energy.sum(axis=-1)[:, self.aa_map_awsem_list] + h[:, 0] = 0 + self.sparse_potts_model = { + 'h': h, + 'J': J_sparse_21, + 'contact_i': ci.astype(np.intp), + 'contact_j': cj.astype(np.intp), + 'L': self.N, + } + self._potts_model = {'h': h, 'J': None} + self._native_energy = None + self.contact_energy = None + + # Electrostatics (from sparse 40Å distance data) + if p.k_electrostatics != 0: + elec_ci, elec_cj, elec_dists, elec_L = self._sparse_distance_matrix_elec + mask_i, mask_j, mask_L = self.mask + self._elec_data = frustration.build_elec_data_sparse( + elec_ci, elec_cj, elec_dists, elec_L, + mask_i, mask_j, mask_L, + self.sequence, self.sparse_potts_model, + p.k_electrostatics, p.electrostatics_screening_length, + p.min_sequence_separation_electrostatics, + chain_breaks=self.chain_breaks, + mask_sequence_cutoff=self.sequence_cutoff if self.distance_cutoff is None else None, + mask_chain_breaks=self.chain_breaks if self.distance_cutoff is None else None, + ) + else: + self._elec_data = None + + # Indicator exposure + if expose: + self._start_indicator_exposure(p) + L = self.N + dense_theta = np.zeros((L, L)) + dense_theta[ci, cj] = theta_c + dense_protein = np.zeros((L, L)) + dense_protein[ci, cj] = thetaII_c * sigma_protein_c + dense_water = np.zeros((L, L)) + dense_water[ci, cj] = thetaII_c * sigma_water_c + self.indicators.append(dense_theta) + self.indicators.append(dense_protein) + self.indicators.append(dense_water) + self.indicator_contact_i = None + self.indicator_contact_j = None + if p.k_electrostatics != 0: + # Reconstruct dense electrostatics indicator from sparse 40Å data + elec_ci, elec_cj, elec_dists, elec_L = self._sparse_distance_matrix_elec + e_mask_ci, e_mask_cj = frustration.compute_mask_sparse( + elec_ci, elec_cj, elec_dists, elec_L, + maximum_contact_distance=None, + minimum_sequence_separation=p.min_sequence_separation_electrostatics, + chain_breaks=self.chain_breaks) + e_dists = self._lookup_sparse_distances(elec_ci, elec_cj, elec_dists, elec_L, e_mask_ci, e_mask_cj) + electrostatics_indicator = np.zeros((L, L)) + with np.errstate(divide='ignore', invalid='ignore'): + vals = np.exp(-e_dists / p.electrostatics_screening_length) / e_dists + vals[np.isnan(vals)] = 0.0 + vals[np.isinf(vals)] = 0.0 + electrostatics_indicator[e_mask_ci, e_mask_cj] = vals + charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) + charges2 = charges[:, np.newaxis] * charges[np.newaxis, :] + self.indicators.append(electrostatics_indicator) + temp_gamma = 0.5 * p.k_electrostatics * charges2[self.aa_map_awsem_x, self.aa_map_awsem_y] + temp_gamma[0, :] = 0 + temp_gamma[:, 0] = 0 + self.gamma_array.append(temp_gamma) + + def _get_configurational_contact_data(self): + """Extract upper-triangle contact distances and indices for configurational frustration. + + Works for both sparse and dense distance matrices. + + Returns + ------- + distances : np.ndarray (C,) + Contact distances (upper triangle, within distance_cutoff_contact). + indices1 : np.ndarray (C,) + Row indices of contacts. + indices2 : np.ndarray (C,) + Column indices of contacts. + """ + if self._distance_is_sparse: + ci, cj, dists, L = self._sparse_distance_matrix + # Upper triangle: ci < cj + upper = ci < cj + uci = ci[upper] + ucj = cj[upper] + udists = dists[upper] + valid = (udists < self.distance_cutoff_contact) & (udists > 0) + return udists[valid], uci[valid], ucj[valid] + else: + dm = self.distance_matrix + n = dm.shape[0] + tri_upper_indices = np.triu_indices(n, k=1) + tri_dists = dm[tri_upper_indices] + valid = (tri_dists < self.distance_cutoff_contact) & (tri_dists > 0) + return tri_dists[valid], tri_upper_indices[0][valid], tri_upper_indices[1][valid] + + def _compute_sigma_at_pairs(self, n1, n2): + """Compute sigma_water and sigma_protein at specific residue pairs. + + Uses pre-computed dense sigma if available, otherwise computes from rho_r. + """ + if self._sigma_water is not None: + return self._sigma_water[n1, n2], self._sigma_protein[n1, n2] + # Sparse mode: compute from rho_r + rho1 = self.rho_r[n1] + rho2 = self.rho_r[n2] + sw = 0.25 * (1 - np.tanh(self.eta_sigma * (rho1 - self.rho_0))) * (1 - np.tanh(self.eta_sigma * (rho2 - self.rho_0))) + return sw, 1 - sw + def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): # ['A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V'] _AA='ARNDCQEGHILKMFPSTWYV' @@ -364,11 +650,8 @@ def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): probabilities = [freq / total for freq in aa_freq.ravel()] seq_index = np.random.choice(a=len(aa_freq), size=N, p=probabilities) - distances = np.triu(self.distance_matrix) - distances = distances[(distances0)] + distances, _, _ = self._get_configurational_contact_data() - sigma_water = self._sigma_water - sigma_protein = self._sigma_protein burial_indicator = self._burial_indicator #Calculate theta and indicators @@ -379,8 +662,6 @@ def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): electrostatics_indicator = np.exp(-distances / self.electrostatics_screening_length) / distances decoy_energies=np.zeros(n_decoys) - #decoy_data=[None]*n_decoys - #decoy_data_columns=['decoy_i','rand_i_resno','rand_j_resno','ires_type','jres_type','i_resno','j_resno','rij','rho_i','rho_j','water_energy','burial_energy_i','burial_energy_j','electrostatic_energy','tert_frust_decoy_energies'] for i in range(n_decoys): c=np.random.randint(0,len(distances)) n1=np.random.randint(0,self.N) @@ -394,14 +675,14 @@ def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): burial_energy1 = (-0.5 * self.k_contact * self.burial_gamma[q1] * burial_indicator[n1]).sum(axis=0) burial_energy2 = (-0.5 * self.k_contact * self.burial_gamma[q2] * burial_indicator[n2]).sum(axis=0) + sigma_water_val, sigma_protein_val = self._compute_sigma_at_pairs(n1, n2) direct = theta[c] * self.direct_gamma[q1, q2] - water_mediated = sigma_water[n1,n2] * thetaII[c] * self.water_gamma[q1,q2] - protein_mediated = sigma_protein[n1,n2] * thetaII[c] * self.protein_gamma[q1,q2] + water_mediated = sigma_water_val * thetaII[c] * self.water_gamma[q1,q2] + protein_mediated = sigma_protein_val * thetaII[c] * self.protein_gamma[q1,q2] contact_energy = -self.k_contact * (direct+water_mediated+protein_mediated) electrostatics_energy = self.k_electrostatics * electrostatics_indicator[c]*charges[q1]*charges[q2] decoy_energies[i]=(burial_energy1+burial_energy2+contact_energy+electrostatics_energy) - #decoy_data[i]=[i, qi1, qi2, q1, q2, n1, n2, distances[c], self.rho_r[n1], self.rho_r[n2], contact_energy/4.184, burial_energy1/4.184, burial_energy2/4.184, electrostatics_energy/4.184, decoy_energies[i]] mean_decoy_energy = np.mean(decoy_energies) std_decoy_energy = np.std(decoy_energies) @@ -410,21 +691,10 @@ def compute_configurational_decoy_statistics(self, n_decoys=4000,aa_freq=None): def compute_configurational_energies(self): _AA='ARNDCQEGHILKMFPSTWYV' seq_index = np.array([_AA.find(aa) for aa in self.sequence]) - distances = np.triu(self.distance_matrix) - distances = distances[(distances0)] + distances, indices1, indices2 = self._get_configurational_contact_data() n_contacts=len(distances) + n = self.N - n = self.distance_matrix.shape[0] # Assuming self.distance_matrix is defined and square - tri_upper_indices = np.triu_indices(n, k=1) # k=1 excludes the diagonal - valid_pairs = (self.distance_matrix[tri_upper_indices] < self.distance_cutoff_contact) & \ - (self.distance_matrix[tri_upper_indices] > 0) - indices1,indices2 = (tri_upper_indices[0][valid_pairs], tri_upper_indices[1][valid_pairs]) - - # for n1,n2,c in zip(indices1,indices2,range(n_contacts)): - # assert self.distance_matrix[n1,n2] == distances[c] - - sigma_water = self._sigma_water - sigma_protein = self._sigma_protein burial_indicator = self._burial_indicator #Calculate theta and indicators @@ -434,8 +704,6 @@ def compute_configurational_energies(self): charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) electrostatics_indicator = np.exp(-distances / self.electrostatics_screening_length) / distances - # decoy_data_columns=['decoy_i','i_resno','j_resno','ires_type','jres_type','aa1','aa2','rij','rho_i','rho_j','water_energy','burial_energy_i','burial_energy_j','electrostatic_energy','total_energies'] - # decoy_data=[] configurational_energies=np.full((n,n), np.nan) # masked pairs will be left as nan for c in range(n_contacts): n1=indices1[c] @@ -446,18 +714,17 @@ def compute_configurational_energies(self): burial_energy1 = (-0.5 * self.k_contact * self.burial_gamma[q1] * burial_indicator[n1]).sum(axis=0) burial_energy2 = (-0.5 * self.k_contact * self.burial_gamma[q2] * burial_indicator[n2]).sum(axis=0) + sigma_water_val, sigma_protein_val = self._compute_sigma_at_pairs(n1, n2) direct = theta[c] * self.direct_gamma[q1, q2] - water_mediated = sigma_water[n1,n2] * thetaII[c] * self.water_gamma[q1,q2] - protein_mediated = sigma_protein[n1,n2] * thetaII[c] * self.protein_gamma[q1,q2] + water_mediated = sigma_water_val * thetaII[c] * self.water_gamma[q1,q2] + protein_mediated = sigma_protein_val * thetaII[c] * self.protein_gamma[q1,q2] contact_energy = -self.k_contact * (direct+water_mediated+protein_mediated) electrostatics_energy = self.k_electrostatics * electrostatics_indicator[c]*charges[q1]*charges[q2] energy=(burial_energy1+burial_energy2+contact_energy+electrostatics_energy) configurational_energies[n1,n2]=energy configurational_energies[n2,n1]=energy - # decoy_data+=[[c, n1, n2, q1, q2, _AA[q1],_AA[q2], distances[c], self.rho_r[n1], self.rho_r[n2], contact_energy/4.184, burial_energy1/4.184, burial_energy2/4.184, electrostatics_energy/4.184, energy/4.184]] - # import pandas as pd - return configurational_energies #, pd.DataFrame(decoy_data, columns=decoy_data_columns) + return configurational_energies def configurational_frustration(self,aa_freq=None, correction=0, n_decoys=4000): mean_decoy_energy, std_decoy_energy = self.compute_configurational_decoy_statistics(n_decoys=n_decoys,aa_freq=aa_freq) diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index b13657ac..db21322e 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -51,6 +51,12 @@ def _is_sparse(self): """True when a sparse Potts model is available.""" return getattr(self, 'sparse_potts_model', None) is not None + def _compute_native_energy_elec(self, sequence, elec_data): + """Dispatch electrostatic native energy to sparse or dense version.""" + if elec_data.get('indicator') is None: + return frustration.compute_native_energy_elec_sparse(sequence, elec_data) + return frustration.compute_native_energy_elec(sequence, elec_data, self.mask) + @property def potts_model(self): """Access the Potts model dict with auto-reconstruction of J from sparse if needed.""" @@ -84,14 +90,14 @@ def native_energy(self,sequence:str = None,ignore_couplings_of_gaps:bool=False,i if self._is_sparse: energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) if getattr(self, '_elec_data', None) is not None: - energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) + energy += self._compute_native_energy_elec(sequence, self._elec_data) return energy return frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) if not self._native_energy: if self._is_sparse: self._native_energy = frustration.compute_native_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps, ignore_fields_of_gaps) if getattr(self, '_elec_data', None) is not None: - self._native_energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) + self._native_energy += self._compute_native_energy_elec(sequence, self._elec_data) else: self._native_energy=frustration.compute_native_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps,ignore_fields_of_gaps) energy_value=self._native_energy @@ -175,7 +181,7 @@ def couplings_energy(self, sequence:str = None,ignore_couplings_of_gaps:bool = F if self._is_sparse: couplings_energy=frustration.compute_couplings_energy_sparse(sequence, self.sparse_potts_model, ignore_couplings_of_gaps) if getattr(self, '_elec_data', None) is not None: - couplings_energy += frustration.compute_native_energy_elec(sequence, self._elec_data, self.mask) + couplings_energy += self._compute_native_energy_elec(sequence, self._elec_data) else: couplings_energy=frustration.compute_couplings_energy(sequence, self.potts_model, self.mask,ignore_couplings_of_gaps) return couplings_energy @@ -216,8 +222,15 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: if _elec_data is not None: fluctuation = frustration.apply_elec_correction_mutational(fluctuation, self.sparse_potts_model, _elec_data) elif kind == 'pseudoconfigurational': - mask_mean = self.mask.mean() - fluctuation = frustration.compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model, mask_mean) + if isinstance(self.mask, tuple): + _mi, _mj, _mL = self.mask + if self.distance_cutoff is None: + _mask_mean = frustration.mask_mean(_mL, self.sequence_cutoff, self.chain_breaks) + else: + _mask_mean = float(len(_mi)) / (_mL * _mL) + else: + _mask_mean = float(self.mask.mean()) + fluctuation = frustration.compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model, _mask_mean) if _elec_data is not None: fluctuation = frustration.apply_elec_correction_pseudoconfigurational(fluctuation, self.sparse_potts_model, _elec_data) elif kind == 'contact': diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index c969ea40..e704d584 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -18,7 +18,7 @@ class Structure: def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_selection: str = None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, - distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None, sparse: bool = True)->object: + distance_matrix_method:str = 'CB', pdb_directory: Path = None, repair_pdb: bool = None, sparse: bool = False)->object: """ Generates structure object. Both PDB and CIF format files are accepted as input. @@ -92,13 +92,62 @@ def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_s def _validate_structure(self): """Check that the structure is internally consistent.""" L_seq = len(self.sequence) - L_dm = self.distance_matrix.shape[0] + dm = self.distance_matrix + if isinstance(dm, tuple): + # Sparse COO: (contact_i, contact_j, distances, L) + L_dm = dm[3] + else: + L_dm = dm.shape[0] if L_seq != L_dm: raise ValueError( f"Sequence length ({L_seq}) does not match distance matrix " - f"shape ({L_dm}x{L_dm}). The PDB may have missing residues. " + f"size ({L_dm}). The PDB may have missing residues. " f"Try setting repair_pdb=True.") + @property + def _is_sparse(self): + """True when sparse distance data is stored and no dense matrix is cached.""" + return self._sparse_distance_matrix is not None and self._dense_distance_matrix is None + + @property + def distance_matrix(self): + """Return dense distance matrix if available, otherwise sparse COO tuple.""" + if self._dense_distance_matrix is not None: + return self._dense_distance_matrix + return self._sparse_distance_matrix + + @distance_matrix.setter + def distance_matrix(self, value): + """Allow direct assignment for backward compatibility.""" + if isinstance(value, tuple): + assert len(value) == 4, "Sparse distance matrix must be a tuple of (contact_i, contact_j, distances, L)" + assert len(value[0]) == len(value[1]) == len(value[2]), "Sparse distance matrix contact_i, contact_j, and distances must have the same length" + assert len(value[0]) == len(self.sequence), f"Sparse distance matrix length ({len(value[0])}) does not match sequence length ({len(self.sequence)})" + self._sparse_distance_matrix = value + self._dense_distance_matrix = None + else: + self._dense_distance_matrix = value + + def get_dense_distance_matrix(self): + """Lazily compute and cache the dense distance matrix from PDB.""" + if self._dense_distance_matrix is None: + self._dense_distance_matrix = pdb.get_dense_distance_matrix( + pdb_file=self.pdb_file, chain=self.chain, + method=self.distance_matrix_method) + # Apply seq_selection slicing if needed + if self.seq_selection is not None: + self._dense_distance_matrix = self._dense_distance_matrix[ + self.init_index_shift:self.fin_index_shift, + self.init_index_shift:self.fin_index_shift] + return self._dense_distance_matrix + + @staticmethod + def _filter_sparse_tuple(sparse_tuple, init, fin): + """Filter a sparse COO tuple to a sub-range [init, fin) and re-index.""" + ci, cj, dists, L = sparse_tuple + keep = (ci >= init) & (ci < fin) & (cj >= init) & (cj < fin) + return (ci[keep] - init, cj[keep] - init, dists[keep], fin - init) + def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, filtered_aligned_sequence, distance_matrix_method, pdb_directory, repair_pdb, sparse): @@ -195,17 +244,27 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self.structure=prody.parseMMCIF(str(self.pdb_file),chain=self.chain).select(f"protein and {self.seq_selection}") self.sequence=pdb.get_sequence(self.pdb_file,self.chain) - self.distance_matrix=pdb.get_dense_distance_matrix(pdb_file=self.pdb_file,chain=self.chain, - method=self.distance_matrix_method) - self.full_pdb_distance_matrix=self.distance_matrix - # Compute sparse distance data if requested + # Distance matrix storage + self._sparse = sparse if sparse: - self.sparse_distance_data = pdb.get_sparse_distance_matrix( + # Compute the less stringent sparse matrix for electrostatic calculations (max_distance=40.0) + # then filter it down for the main sparse matrix (max_distance=15.0) + self._sparse_distance_matrix_elec = pdb.get_sparse_distance_matrix( pdb_file=self.pdb_file, chain=self.chain, - method=self.distance_matrix_method, max_distance=15.0) + method=self.distance_matrix_method, max_distance=40.0) + ci, cj, dists, L = self._sparse_distance_matrix_elec + keep = dists <= 15.0 + self._sparse_distance_matrix = (ci[keep], cj[keep], dists[keep], L) + self._dense_distance_matrix = None else: - self.sparse_distance_data = None + self._dense_distance_matrix = pdb.get_dense_distance_matrix( + pdb_file=self.pdb_file, chain=self.chain, + method=self.distance_matrix_method) + self._sparse_distance_matrix = None + self._sparse_distance_matrix_elec = None + + self.full_pdb_distance_matrix = self.distance_matrix self.z_coordinates=self.structure.select('((name CB) or (resname GLY and name CA))').getCoords() @@ -216,27 +275,38 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self.chain_breaks = breaks.tolist() if len(breaks) > 0 else None if self.seq_selection!=None: - self.distance_matrix=self.distance_matrix[self.init_index_shift:self.fin_index_shift, - self.init_index_shift:self.fin_index_shift] + if self._is_sparse: + self._sparse_distance_matrix = self._filter_sparse_tuple( + self._sparse_distance_matrix, self.init_index_shift, self.fin_index_shift) + self._sparse_distance_matrix_elec = self._filter_sparse_tuple( + self._sparse_distance_matrix_elec, self.init_index_shift, self.fin_index_shift) + else: + self._dense_distance_matrix = self._dense_distance_matrix[ + self.init_index_shift:self.fin_index_shift, + self.init_index_shift:self.fin_index_shift] self.sequence=self.sequence[self.init_index_shift:self.fin_index_shift] if self.aligned_sequence is not None: + if self._is_sparse: + raise NotImplementedError( + "aligned_sequence is not supported with sparse distance matrices. " + "Use sparse=False or call get_dense_distance_matrix() first.") self.full_to_aligned_index_dict=pdb.full_to_filtered_aligned_mapping(self.aligned_sequence,self.filtered_aligned_sequence) self.mapped_distance_matrix=np.full((len(self.filtered_aligned_sequence), len(self.filtered_aligned_sequence)), np.inf) pos1, pos2 = np.meshgrid(list(self.full_to_aligned_index_dict.keys()), list(self.full_to_aligned_index_dict.keys()), indexing='ij', sparse=True) modpos1, modpos2 = np.meshgrid(list(self.full_to_aligned_index_dict.values()), list(self.full_to_aligned_index_dict.values()), indexing='ij', sparse=True) - self.mapped_distance_matrix[modpos1,modpos2]=self.distance_matrix[pos1,pos2] + self.mapped_distance_matrix[modpos1,modpos2]=self._dense_distance_matrix[pos1,pos2] np.fill_diagonal(self.mapped_distance_matrix, 0) else: if self.seq_selection==None: self.full_to_aligned_index_dict=dict(zip(range(len(self.sequence)), range(len(self.sequence)))) - self.mapped_distance_matrix=self.distance_matrix + self.mapped_distance_matrix=self.distance_matrix if not self._is_sparse else None else: self.full_to_aligned_index_dict=dict(zip(range(self.init_index_shift,self.fin_index_shift+1), range(len(self.sequence)))) - self.mapped_distance_matrix=self.distance_matrix + self.mapped_distance_matrix=self.distance_matrix if not self._is_sparse else None @classmethod def from_pdb_list(cls, pdb_files, chain=None, pdb_directory=None, repair_pdb=None, **kwargs): @@ -313,6 +383,45 @@ def spliced_pdb(cls,pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_ distance_matrix_method=distance_matrix_method, pdb_directory=pdb_directory, repair_pdb=repair_pdb,) + + def plot_distance_map(self, interaction_type: bool = False, config=None, + ax=None, **kwargs): + """Plot the inter-residue distance map. + + Parameters + ---------- + interaction_type : bool + If True, colour contacts by interaction band. + config : PlotConfig, optional + Visual settings. Fields can also be overridden via **kwargs. + ax : matplotlib Axes, optional + Axes to draw on. + **kwargs + Forwarded to PlotConfig (e.g. ``vmax=15``, ``cmap='hot'``). + + Returns + ------- + matplotlib Axes + """ + chain_label = f' chain {self.chain}' if self.chain else '' + mode = 'sparse' if self._is_sparse else 'dense' + kwargs.setdefault('title', f'Distance Map ({mode}){chain_label}') + + if self._is_sparse: + sparse_dm = getattr(self, '_sparse_distance_matrix_elec', + None) or self._sparse_distance_matrix + if interaction_type: + return pdb.plot_sparse_interaction_map( + sparse_dm, config=config, ax=ax, **kwargs) + return pdb.plot_sparse_distance_map( + sparse_dm, config=config, ax=ax, **kwargs) + else: + if interaction_type: + return pdb.plot_interaction_map( + self.distance_matrix, config=config, ax=ax, **kwargs) + return pdb.plot_distance_map( + self.distance_matrix, config=config, ax=ax, **kwargs) + # @property # def sequence(self): # return self._sequence diff --git a/frustratometer/frustration/__init__.py b/frustratometer/frustration/__init__.py index 9074192c..7ab1953a 100644 --- a/frustratometer/frustration/__init__.py +++ b/frustratometer/frustration/__init__.py @@ -41,4 +41,7 @@ 'apply_elec_correction_mutational', 'apply_elec_correction_contact', 'apply_elec_correction_pseudoconfigurational', + 'build_elec_data_sparse', + 'compute_native_energy_elec_sparse', + 'mask_mean', ] diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index 8086c881..eee1ba3c 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -1663,6 +1663,68 @@ def compute_mask_sparse(contact_i: np.ndarray, return contact_i[keep], contact_j[keep] +def mask_mean(L: int, minimum_sequence_separation: Union[int, None] = None, chain_breaks: Union[list, None] = None): + """ + Compute the fraction of valid residue pairs analytically for a sequence-separation-only mask. + + Instead of constructing the full (L, L) boolean mask and calling `.mean()`, this + function counts the number of excluded pairs directly and returns the valid fraction. + This is used as a normalization factor for pseudoconfigurational frustration calculations. + + Parameters + ---------- + L : int + The number of residues (sequence length). The full mask would have shape (L, L). + minimum_sequence_separation : int, optional + Minimum sequence separation |i - j| required for a pair to be included. + Pairs with |i - j| < minimum_sequence_separation are excluded. + If None, no sequence-separation filtering is applied and 1.0 is returned. + Default is None. + chain_breaks : list of int, optional + Indices where new chains begin (excluding the implicit 0). For example, [50, 80] + means three chains: residues 0–49, 50–79, 80–end. Cross-chain pairs always satisfy + the minimum sequence separation criterion since they are not bonded in sequence. + If None, all residues are treated as a single chain. Default is None. + + Returns + ------- + fraction : float + The fraction of the (L, L) pairs that pass the sequence-separation filter, + equivalent to ``compute_mask(distance_matrix, minimum_sequence_separation=minimum_sequence_separation, + chain_breaks=chain_breaks).mean()`` but computed without building the full matrix. + + Examples + -------- + >>> mask_mean(10, minimum_sequence_separation=2) + 0.8 # (100 - 20) / 100 + + Notes + ----- + Without chain breaks, the number of excluded pairs is: + L (diagonal) + 2*(L-1) + 2*(L-2) + ... + 2*(L - minimum_sequence_separation + 1). + + With chain breaks, positions are offset so that inter-chain distances are + artificially inflated, ensuring cross-chain pairs always pass the filter. + """ + if chain_breaks is None or len(chain_breaks) == 0: + n_excluded = L # diagonal (|i-j| = 0) + for k in range(1, minimum_sequence_separation): + n_excluded += 2 * (L - k) + return float(L * L - n_excluded) / (L * L) + else: + # With chain breaks, use position-offsetting approach + positions = np.arange(L, dtype=np.float64) + for brk in chain_breaks: + positions[brk:] += minimum_sequence_separation + # Count valid pairs efficiently via sorted positions + binary search + sorted_pos = np.sort(positions) + n_excluded = 0 + for i in range(L): + lo = np.searchsorted(sorted_pos, positions[i] - minimum_sequence_separation + 1e-9, side='left') + hi = np.searchsorted(sorted_pos, positions[i] + minimum_sequence_separation - 1e-9, side='right') + n_excluded += hi - lo + return float(L * L - n_excluded) / (L * L) + def potts_model_dense_to_sparse(potts_model: dict, mask: np.ndarray) -> dict: """ @@ -2301,6 +2363,178 @@ def compute_native_energy_elec(sequence: str, return energy +def build_elec_data_sparse(elec_ci: np.ndarray, + elec_cj: np.ndarray, + elec_dists: np.ndarray, + elec_L: int, + mask_i: np.ndarray, + mask_j: np.ndarray, + mask_L: int, + sequence: str, + sparse_potts_model: dict, + k_electrostatics: float = 17.3636, + screening_length: float = 10.0, + min_sequence_separation_electrostatics: int = 1, + chain_breaks: list = None, + mask_sequence_cutoff: int = None, + mask_chain_breaks: list = None) -> dict: + """ + Build electrostatic data from sparse COO distance arrays. + + Parameters + ---------- + elec_ci, elec_cj : np.ndarray + Row/col indices from the 40A sparse distance matrix. + elec_dists : np.ndarray + Distances for each (i,j) pair. + elec_L : int + Sequence length. + mask_i, mask_j : np.ndarray + Row/col indices of the frustration mask (contacts within the mask). + mask_L : int + Sequence length (should equal elec_L). + sequence : str + Amino acid sequence. + sparse_potts_model : dict + Sparse Potts model with 'contact_i', 'contact_j'. + k_electrostatics : float + Electrostatic coupling coefficient. + screening_length : float + Debye-Hückel screening length. + min_sequence_separation_electrostatics : int + Minimum sequence separation for electrostatic interactions. + chain_breaks : list, optional + Chain break positions. + mask_sequence_cutoff : int, optional + When provided, check sequence separation directly for mask membership + instead of using mask_i/mask_j. This avoids the mask being limited by + the sparse distance cutoff. + mask_chain_breaks : list, optional + Chain breaks for the mask sequence separation check. + + Returns + ------- + elec_data : dict + Same keys as ``build_elec_data`` output. + """ + seq_index = np.array([_AA.find(aa) for aa in sequence]) + L = len(seq_index) + charges = _CHARGES + q_native = charges[seq_index] + + # Apply electrostatic sequence separation to full elec sparse data + filt_ci, filt_cj = compute_mask_sparse( + elec_ci, elec_cj, elec_dists, elec_L, + maximum_contact_distance=None, + minimum_sequence_separation=min_sequence_separation_electrostatics, + chain_breaks=chain_breaks) + + # Build a lookup for filtered elec distances + # We need the distances at (filt_ci, filt_cj) positions + # Create index mapping from original elec arrays + elec_key = elec_ci.astype(np.int64) * elec_L + elec_cj.astype(np.int64) + filt_key = filt_ci.astype(np.int64) * elec_L + filt_cj.astype(np.int64) + # Find matching indices + sort_idx = np.argsort(elec_key) + filt_pos = np.searchsorted(elec_key, filt_key, sorter=sort_idx) + filt_dists = elec_dists[sort_idx[filt_pos]] + + # Indicator values at filtered positions + with np.errstate(divide='ignore', invalid='ignore'): + ind_vals = -k_electrostatics * np.exp(-filt_dists / screening_length) / filt_dists + ind_vals[np.isnan(ind_vals)] = 0.0 + ind_vals[np.isinf(ind_vals)] = 0.0 + + # Build set of mask entries for fast lookup + ind_masked = ind_vals.copy() + if mask_sequence_cutoff is not None: + # Check sequence separation directly (mask not limited by sparse distance cutoff) + def _check_seqsep(arr_i, arr_j, seq_cutoff, brks): + pos_i = arr_i.astype(np.float64) + pos_j = arr_j.astype(np.float64) + if brks is not None: + for brk in brks: + pos_i = np.where(arr_i >= brk, pos_i + seq_cutoff, pos_i) + pos_j = np.where(arr_j >= brk, pos_j + seq_cutoff, pos_j) + return np.abs(pos_i - pos_j) >= seq_cutoff + + filt_in_mask = _check_seqsep(filt_ci, filt_cj, mask_sequence_cutoff, mask_chain_breaks) + else: + mask_key = mask_i.astype(np.int64) * L + mask_j.astype(np.int64) + mask_set = set(mask_key.tolist()) + filt_in_mask = np.array([int(ci_v) * L + int(cj_v) in mask_set + for ci_v, cj_v in zip(filt_ci, filt_cj)]) + ind_masked[~filt_in_mask] = 0.0 + + # phi = indicator * mask @ q_native per row i + phi = np.bincount(filt_ci, weights=ind_masked * q_native[filt_cj], minlength=L).astype(np.float64) + # phi_raw = indicator @ q_native per row i (unmasked) + phi_raw = np.bincount(filt_ci, weights=ind_vals * q_native[filt_cj], minlength=L).astype(np.float64) + + # Indicator at Potts contact positions + potts_ci = sparse_potts_model['contact_i'] + potts_cj = sparse_potts_model['contact_j'] + potts_key = potts_ci.astype(np.int64) * L + potts_cj.astype(np.int64) + + # Build lookup from filtered elec data + ind_lookup = {} + for k, v in zip(filt_key, ind_vals): + ind_lookup[int(k)] = v + + indicator_at_contacts = np.array([ind_lookup.get(int(k), 0.0) for k in potts_key]) + if mask_sequence_cutoff is not None: + mask_at_contacts = _check_seqsep(potts_ci, potts_cj, mask_sequence_cutoff, mask_chain_breaks).astype(float) + else: + mask_at_contacts = np.array([1.0 if int(k) in mask_set else 0.0 for k in potts_key]) + + if mask_sequence_cutoff is not None: + _mask_mean = mask_mean(L, mask_sequence_cutoff, mask_chain_breaks) + else: + _mask_mean = float(len(mask_i)) / (L * L) + + return { + 'charges': charges, + 'q_var': _Q_VAR, + 'q_native': q_native, + 'indicator': None, # No dense indicator in sparse mode + 'indicator_at_contacts': indicator_at_contacts, + 'phi': phi, + 'phi_raw': phi_raw, + 'mask_at_contacts': mask_at_contacts, + 'mask_mean': _mask_mean, + # Sparse representation for reconstructing dense indicator_masked if needed + 'indicator_masked_i': filt_ci[filt_in_mask], + 'indicator_masked_j': filt_cj[filt_in_mask], + 'indicator_masked_vals': ind_masked[filt_in_mask], + 'L': L, + } + + +def compute_native_energy_elec_sparse(sequence: str, + elec_data: dict) -> float: + """ + Compute the electrostatic contribution to native energy from sparse elec_data. + + Uses phi vectors instead of full indicator matrix. + + Parameters + ---------- + sequence : str + Amino acid sequence. + elec_data : dict + Electrostatic data from ``build_elec_data_sparse``. + + Returns + ------- + energy : float + """ + q_native = elec_data['q_native'] + phi = elec_data['phi'] + # E = -0.5 * sum_i q_i * phi_i where phi_i = sum_j indicator_ij * mask_ij * q_j + energy = -0.5 * (q_native * phi).sum() + return energy + + def apply_elec_correction_singleresidue(decoy_fluctuation: np.ndarray, elec_data: dict) -> np.ndarray: """ diff --git a/frustratometer/optimization/optimization.py b/frustratometer/optimization/optimization.py index d71ef42b..31db9d50 100644 --- a/frustratometer/optimization/optimization.py +++ b/frustratometer/optimization/optimization.py @@ -404,7 +404,20 @@ def __init__(self, model: Frustratometer, alphabet: str = _AA, use_numba: bool = elec_data = getattr(model, '_elec_data', None) if elec_data is not None: from frustratometer.frustration.frustration import _CHARGES - self.indicator_masked = elec_data['indicator'] * model.mask # (L, L) + if elec_data['indicator'] is not None: + # Dense mode: indicator is (L, L) + mask = model.mask + if isinstance(mask, tuple): + mask_i, mask_j, mask_L = mask + mask = np.zeros((mask_L, mask_L), dtype=float) + mask[mask_i, mask_j] = 1.0 + self.indicator_masked = elec_data['indicator'] * mask # (L, L) + else: + # Sparse mode: reconstruct dense indicator_masked from sparse data + eL = elec_data['L'] + self.indicator_masked = np.zeros((eL, eL), dtype=float) + self.indicator_masked[elec_data['indicator_masked_i'], + elec_data['indicator_masked_j']] = elec_data['indicator_masked_vals'] self.elec_charges = _CHARGES.copy() # (21,) in DCA alphabet else: self.indicator_masked = None diff --git a/frustratometer/pdb/__init__.py b/frustratometer/pdb/__init__.py index 956b4d1f..e8adb035 100644 --- a/frustratometer/pdb/__init__.py +++ b/frustratometer/pdb/__init__.py @@ -14,6 +14,8 @@ from .pdb import * from .distance import get_dense_distance_matrix, get_sparse_distance_matrix +from .plotting import (PlotConfig, plot_distance_map, plot_interaction_map, + plot_sparse_distance_map, plot_sparse_interaction_map) try: from .fix import repair_pdb, repair_pdbs except ImportError as e: @@ -33,5 +35,8 @@ def warn_pdbfixer_not_installed(): ) else: raise e - -__all__ = ['download', 'get_sequence', 'get_dense_distance_matrix', 'get_sparse_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs'] \ No newline at end of file + +__all__ = ['download', 'get_sequence', 'get_dense_distance_matrix', 'get_sparse_distance_matrix', + 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs', + 'PlotConfig', 'plot_distance_map', 'plot_interaction_map', + 'plot_sparse_distance_map', 'plot_sparse_interaction_map'] \ No newline at end of file diff --git a/frustratometer/pdb/plotting.py b/frustratometer/pdb/plotting.py new file mode 100644 index 00000000..1fd06c7e --- /dev/null +++ b/frustratometer/pdb/plotting.py @@ -0,0 +1,186 @@ +"""Plotting utilities for distance matrices (dense and sparse). + +Four public functions, all using imshow: + +- ``plot_distance_map`` – dense L×L, continuous 0-to-vmax colourmap +- ``plot_interaction_map`` – dense L×L, categorical band colours +- ``plot_sparse_distance_map`` – sparse COO → temporary L×L with NaN gaps +- ``plot_sparse_interaction_map`` – sparse COO → temporary L×L with NaN gaps + +All accept an optional ``PlotConfig`` (pydantic) for visual settings. +Any config field can also be overridden as a keyword argument. +""" + +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +from matplotlib.patches import Patch +from pydantic import BaseModel +from typing import Tuple, Optional + +__all__ = [ + 'PlotConfig', + 'plot_distance_map', + 'plot_interaction_map', + 'plot_sparse_distance_map', + 'plot_sparse_interaction_map', +] + + +# --------------------------------------------------------------------------- +# Configuration +# --------------------------------------------------------------------------- + +class PlotConfig(BaseModel): + """Visual settings shared by all distance-map plots.""" + vmax: float = 10.0 + cmap: str = 'YlGnBu' + figsize: Tuple[float, float] = (7, 6) + title: str = '' + nan_color: str = 'white' + # Interaction-band colours + close_color: str = '#1a1a2e' + direct_color: str = '#e63946' + mediated_color: str = '#f4a261' + electrostatic_color: str = '#457b9d' + interaction_bg: str = '#e8ecf1' + + +# --------------------------------------------------------------------------- +# Internal helpers +# --------------------------------------------------------------------------- + +def _resolve_config(config: Optional[PlotConfig], **kwargs) -> PlotConfig: + """Merge *config* with keyword overrides.""" + if config is None: + config = PlotConfig() + if kwargs: + config = config.model_copy(update=kwargs) + return config + + +def _sparse_to_dense(sparse_dm) -> np.ndarray: + """Convert a COO tuple ``(i, j, dist, L)`` to an L×L array with NaN gaps.""" + ci, cj, dists, L = sparse_dm + mat = np.full((L, L), np.nan) + mat[ci, cj] = dists + return mat + + +def _setup_ax(ax, L: int, title: str): + """Shared axis decoration.""" + ax.set_xlabel('Residue index') + ax.set_ylabel('Residue index') + if title: + ax.set_title(title) + + +def _build_interaction_rgba(matrix: np.ndarray, cfg: PlotConfig) -> np.ndarray: + """Build an RGBA image from band classification. + + Shared by both dense and sparse interaction plots. + """ + L = matrix.shape[0] + rgba = np.zeros((L, L, 4)) + + bands = [ + (0.0, 4.5, cfg.close_color), + (4.5, 6.5, cfg.direct_color), + (6.5, 9.5, cfg.mediated_color), + (9.5, 40.0, cfg.electrostatic_color), + ] + for lo, hi, colour in bands: + if lo == 0: + mask = (matrix > 0) & (matrix < hi) + else: + mask = (matrix >= lo) & (matrix < hi) + r, g, b = mcolors.to_rgb(colour) + rgba[mask] = [r, g, b, 1.0] + + return rgba + + +def _add_interaction_legend(ax, cfg: PlotConfig): + """Add legend for the three named interaction bands (not close).""" + handles = [ + Patch(facecolor=cfg.direct_color, label='Direct (4.5–6.5 Å)'), + Patch(facecolor=cfg.mediated_color, label='Mediated (6.5–9.5 Å)'), + Patch(facecolor=cfg.electrostatic_color, label='Electrostatic (9.5–40 Å)'), + ] + ax.legend(handles=handles, loc='upper left', fontsize=8, framealpha=0.9) + + +# --------------------------------------------------------------------------- +# Public API – dense +# --------------------------------------------------------------------------- + +def plot_distance_map( + distance_matrix: np.ndarray, + config: Optional[PlotConfig] = None, + ax: Optional[plt.Axes] = None, + **kwargs, +) -> plt.Axes: + """Plot a dense distance matrix with a continuous colourmap (0 → vmax).""" + cfg = _resolve_config(config, **kwargs) + + if ax is None: + _, ax = plt.subplots(figsize=cfg.figsize) + + cmap = plt.get_cmap(cfg.cmap).copy() + cmap.set_bad(cfg.nan_color) + + im = ax.imshow(distance_matrix, cmap=cmap, vmin=0, vmax=cfg.vmax, + origin='lower', interpolation='nearest', aspect='equal') + _setup_ax(ax, distance_matrix.shape[0], cfg.title) + plt.colorbar(im, ax=ax, label='Distance (Å)', shrink=0.82) + return ax + + +def plot_interaction_map( + distance_matrix: np.ndarray, + config: Optional[PlotConfig] = None, + ax: Optional[plt.Axes] = None, + **kwargs, +) -> plt.Axes: + """Plot a dense distance matrix coloured by interaction band.""" + cfg = _resolve_config(config, **kwargs) + + if ax is None: + _, ax = plt.subplots(figsize=cfg.figsize) + + L = distance_matrix.shape[0] + rgba = _build_interaction_rgba(distance_matrix, cfg) + + ax.set_facecolor(cfg.interaction_bg) + ax.imshow(rgba, origin='lower', interpolation='nearest', aspect='equal') + _setup_ax(ax, L, cfg.title) + _add_interaction_legend(ax, cfg) + return ax + + +# --------------------------------------------------------------------------- +# Public API – sparse (COO → imshow with NaN for missing) +# --------------------------------------------------------------------------- + +def plot_sparse_distance_map( + sparse_distance_matrix: Tuple[np.ndarray, np.ndarray, np.ndarray, int], + config: Optional[PlotConfig] = None, + ax: Optional[plt.Axes] = None, + **kwargs, +) -> plt.Axes: + """Plot a sparse COO distance matrix as an imshow with NaN gaps.""" + cfg = _resolve_config(config, **kwargs) + matrix = _sparse_to_dense(sparse_distance_matrix) + return plot_distance_map(matrix, config=cfg, ax=ax) + + +def plot_sparse_interaction_map( + sparse_distance_matrix: Tuple[np.ndarray, np.ndarray, np.ndarray, int], + config: Optional[PlotConfig] = None, + ax: Optional[plt.Axes] = None, + **kwargs, +) -> plt.Axes: + """Plot a sparse COO distance matrix coloured by interaction band.""" + cfg = _resolve_config(config, **kwargs) + matrix = _sparse_to_dense(sparse_distance_matrix) + return plot_interaction_map(matrix, config=cfg, ax=ax) diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index d4ba03de..5baaece7 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -37,7 +37,7 @@ def awsem_6u5e(): @pytest.fixture(scope="module") def awsem_6u5e_density(): """6u5e + AWSEM(cutoff=9.499, sep=2, k_elec=0) — shared by single-residue energy/decoy tests.""" - structure = frustratometer.Structure(test_data_path / '6u5e.pdb', "A") + structure = frustratometer.Structure(test_data_path / '6u5e.pdb', "A", sparse=False) return frustratometer.AWSEM(structure, distance_cutoff_contact=9.499, min_sequence_separation_contact=2, @@ -252,7 +252,7 @@ def test_contact_pair_AWSEM_energy(): lammps_mutational_frustration_dataframe["i"]=lammps_mutational_frustration_dataframe["i"]-1 lammps_mutational_frustration_dataframe["j"]=lammps_mutational_frustration_dataframe["j"]-1 ### - structure=frustratometer.Structure(test_data_path/f'6u5e.pdb',"A") + structure=frustratometer.Structure(test_data_path/f'6u5e.pdb',"A", sparse=False) model=frustratometer.AWSEM(structure,distance_cutoff_contact=9.499, min_sequence_separation_contact=0, k_electrostatics=0) @@ -361,7 +361,7 @@ def test_contact_pair_decoy_AWSEM_energy_statistics(): lammps_mutational_frustration_dataframe["i"]=lammps_mutational_frustration_dataframe["i"]-1 lammps_mutational_frustration_dataframe["j"]=lammps_mutational_frustration_dataframe["j"]-1 ### - structure=frustratometer.Structure(test_data_path/f'6u5e.pdb',"A") + structure=frustratometer.Structure(test_data_path/f'6u5e.pdb',"A", sparse=False) model=frustratometer.AWSEM(structure,distance_cutoff_contact=9.5, min_sequence_separation_contact=None, k_electrostatics=0) spm = model.sparse_potts_model ci, cj = spm['contact_i'], spm['contact_j'] @@ -747,25 +747,32 @@ def test_sparse_dense_frustration(fixture_name, kind, sparse_vs_dense_2ghy, spar def test_sparse_dense_chain_breaks_preserved(): """Verify chain_breaks are correctly propagated in both sparse and dense.""" - structure = frustratometer.Structure(test_data_path / '2GHY.pdb') - sparse_m = frustratometer.AWSEM(structure, sparse=True) - dense_m = frustratometer.AWSEM(structure, sparse=False) + structure_sparse = frustratometer.Structure(test_data_path / '2GHY.pdb', sparse=True) + structure_dense = frustratometer.Structure(test_data_path / '2GHY.pdb', sparse=False) + sparse_m = frustratometer.AWSEM(structure_sparse, sparse=True) + dense_m = frustratometer.AWSEM(structure_dense, sparse=False) assert sparse_m.chain_breaks == [57] assert dense_m.chain_breaks == [57] - np.testing.assert_array_equal(sparse_m.mask, dense_m.mask) + # In sparse mode, mask only covers pairs in the sparse distance matrix. + # Verify that every sparse mask pair is also in the dense mask. + mask_i, mask_j, mask_L = sparse_m.mask + assert np.all(dense_m.mask[mask_i, mask_j]) def test_sparse_dense_multichain_elec_energy(): """Electrostatics energy on multichain 2GHY must match between sparse and dense.""" - structure = frustratometer.Structure(test_data_path / '2GHY.pdb') + structure_sparse = frustratometer.Structure(test_data_path / '2GHY.pdb', sparse=True) + structure_dense = frustratometer.Structure(test_data_path / '2GHY.pdb', sparse=False) params = dict(k_electrostatics=4 * 4.184, min_sequence_separation_contact=0, distance_cutoff_contact=9.5, min_sequence_separation_electrostatics=1) - sparse_m = frustratometer.AWSEM(structure, sparse=True, **params) - dense_m = frustratometer.AWSEM(structure, sparse=False, **params) - np.testing.assert_allclose(sparse_m.native_energy(), dense_m.native_energy(), atol=1e-4) - np.testing.assert_allclose(sparse_m.couplings_energy(), dense_m.couplings_energy(), atol=1e-4) + sparse_m = frustratometer.AWSEM(structure_sparse, sparse=True, **params) + dense_m = frustratometer.AWSEM(structure_dense, sparse=False, **params) + # Sparse path uses 40A cutoff for electrostatics; a few distant cross-chain + # pairs (>40A) are absent, causing small numeric differences. + np.testing.assert_allclose(sparse_m.native_energy(), dense_m.native_energy(), atol=0.02) + np.testing.assert_allclose(sparse_m.couplings_energy(), dense_m.couplings_energy(), atol=0.02) if __name__ == "__main__": diff --git a/tests/test_sparse_distance.py b/tests/test_sparse_distance.py index 003220dd..f0ccdacf 100644 --- a/tests/test_sparse_distance.py +++ b/tests/test_sparse_distance.py @@ -48,12 +48,12 @@ def test_sparse_cutoff_respected(): def test_structure_sparse_flag(): - """sparse=True populates sparse_distance_data; False leaves it None.""" + """sparse=True populates _sparse_distance_matrix; False leaves it None.""" import frustratometer s_on = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=True) - assert s_on.sparse_distance_data is not None - ci, cj, d, L = s_on.sparse_distance_data + assert s_on._sparse_distance_matrix is not None + ci, cj, d, L = s_on._sparse_distance_matrix assert L == len(s_on.sequence) s_off = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=False) - assert s_off.sparse_distance_data is None + assert s_off._sparse_distance_matrix is None diff --git a/tests/test_structure.py b/tests/test_structure.py index e3968b9f..8eb4db10 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -21,7 +21,9 @@ def test_structure_valid(pdb, chain, repair_pdb, expect_repair, tmp_path): """Structure should be consistent and only call PDBFixer when expected.""" s = frustratometer.Structure(test_data_path / pdb, chain, repair_pdb=repair_pdb, pdb_directory=tmp_path) - assert len(s.sequence) == s.distance_matrix.shape[0] + dm = s.distance_matrix + L = dm[3] if isinstance(dm, tuple) else dm.shape[0] + assert len(s.sequence) == L cleaned_files = list(tmp_path.glob("*_cleaned.pdb")) was_repaired = len(cleaned_files) > 0 assert was_repaired == expect_repair, ( @@ -51,7 +53,9 @@ def test_from_pdb_list(repair_pdb, tmp_path): repair_pdb=repair_pdb) assert len(structures) == 2 for s in structures: - assert len(s.sequence) == s.distance_matrix.shape[0] + dm = s.distance_matrix + L = dm[3] if isinstance(dm, tuple) else dm.shape[0] + assert len(s.sequence) == L def test_repair_pdb_no_memory_leak(tmp_path): From 756f1fde86d23e69701ac09508b47bd18488531a Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 13 Apr 2026 14:23:11 -0500 Subject: [PATCH 17/28] Adds class for sparse matrix --- frustratometer/classes/AWSEM.py | 109 +++++----------- frustratometer/classes/Frustratometer.py | 8 +- frustratometer/classes/Structure.py | 28 ++-- frustratometer/frustration/frustration.py | 47 ++++--- frustratometer/optimization/optimization.py | 7 +- frustratometer/pdb/__init__.py | 1 + frustratometer/pdb/distance.py | 26 ++-- frustratometer/pdb/plotting.py | 7 +- frustratometer/pdb/sparse.py | 135 ++++++++++++++++++++ tests/test_sparse_distance.py | 26 ++-- tests/test_sparse_potts.py | 4 +- tests/test_structure.py | 5 +- 12 files changed, 247 insertions(+), 156 deletions(-) create mode 100644 frustratometer/pdb/sparse.py diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index 85f6ef6d..3df37c53 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -1,6 +1,7 @@ import numpy as np from ..utils import _path from .. import frustration +from ..pdb.sparse import SparseDistanceMatrix from .Frustratometer import Frustratometer from .Gamma import Gamma from pydantic import BaseModel, Field, ConfigDict @@ -55,7 +56,7 @@ class AWSEM(Frustratometer): aa_map_awsem_x, aa_map_awsem_y = np.meshgrid(aa_map_awsem_list, aa_map_awsem_list, indexing='ij') def __init__(self, - pdb_structure: Frustratometer.Structure, + pdb_structure: 'Structure', sequence: str =None, expose_indicator_functions: bool=False, sparse: bool=True, @@ -124,8 +125,6 @@ def __init__(self, #Sparse matrices self._sparse_distance_matrix = None self._sparse_distance_matrix_elec = None - #Full matrices - self.distance_matrix = dense_dm if self._distance_is_sparse: self._sparse_distance_matrix = pdb_structure._sparse_distance_matrix self._sparse_distance_matrix_elec = pdb_structure._sparse_distance_matrix_elec @@ -161,72 +160,34 @@ def __init__(self, else: self._init_from_dense_distances(p, sparse, expose_indicator_functions, pdb_structure) - def _lookup_sparse_distances(self, ci, cj, dists, L, query_i, query_j): - """Look up distances at specific (i, j) positions from a sparse COO distance array. - - Equivalent to ``dense_matrix[query_i, query_j]`` but without materialising the - full L×L matrix. Each (row, col) pair is encoded as a single integer key - ``i * L + j``, the source keys are sorted once, and all query keys are resolved - in a single vectorised binary search. - - Parameters - ---------- - ci, cj : np.ndarray (N_stored,) - Row and column indices of all stored pairs in the sparse array. - dists : np.ndarray (N_stored,) - Distance values corresponding to each (ci, cj) pair. - L : int - Sequence length (used for the flat key encoding ``i * L + j``). - query_i, query_j : np.ndarray (N_query,) - Row and column indices of the pairs whose distances are requested. - - Returns - ------- - np.ndarray (N_query,) - Distances at the requested positions, in the same order as the queries. - - Notes - ----- - Every (query_i[k], query_j[k]) pair **must** exist in (ci, cj). If a query - pair is absent, ``np.searchsorted`` returns a wrong position and a silent - garbage value is returned — no bounds check is performed. This is safe in - practice because callers always pass indices that were produced by filtering - the same sparse source (e.g. the output of ``compute_mask_sparse``). - """ - src_key = ci.astype(np.int64) * L + cj.astype(np.int64) - qry_key = query_i.astype(np.int64) * L + query_j.astype(np.int64) - sort_idx = np.argsort(src_key) - pos = np.searchsorted(src_key, qry_key, sorter=sort_idx) - return dists[sort_idx[pos]] - def _init_from_sparse_distances(self, p, sparse, expose, pdb_structure): """Initialize AWSEM physics from sparse COO distance data (no L×L arrays).""" - dm_ci, dm_cj, dm_dists, dm_L = self._sparse_distance_matrix + dm = self._sparse_distance_matrix # --- Rho computation --- if self.burial_in_context: full_dm = self.full_pdb_distance_matrix - if isinstance(full_dm, tuple): - sel_ci, sel_cj, sel_dists, sel_L = full_dm + if isinstance(full_dm, SparseDistanceMatrix): + sel_dm = full_dm else: - # Full PDB is dense but selection is sparse — fallback to dense rho - sel_ci, sel_cj, sel_dists, sel_L = dm_ci, dm_cj, dm_dists, dm_L + # Full PDB is dense but selection is sparse — fallback + sel_dm = dm else: - sel_ci, sel_cj, sel_dists, sel_L = dm_ci, dm_cj, dm_dists, dm_L + sel_dm = dm # Rho sequence separation mask - rho_mi, rho_mj = frustration.compute_mask_sparse( - sel_ci, sel_cj, sel_dists, sel_L, + rho_mask = frustration.compute_mask_sparse( + sel_dm.row, sel_dm.col, sel_dm.data, sel_dm.shape, maximum_contact_distance=None, minimum_sequence_separation=p.min_sequence_separation_rho, chain_breaks=self.chain_breaks) - rho_dists = self._lookup_sparse_distances(sel_ci, sel_cj, sel_dists, sel_L, rho_mi, rho_mj) + rho_dists = sel_dm.lookup(rho_mask.row, rho_mask.col) rho_vals = 0.25 * (1 + np.tanh(p.eta * (rho_dists - p.r_min))) * (1 + np.tanh(p.eta * (p.r_max - rho_dists))) - rho_r = np.bincount(rho_mi, weights=rho_vals, minlength=sel_L).astype(np.float64) + rho_r = np.bincount(rho_mask.row, weights=rho_vals, minlength=sel_dm.shape).astype(np.float64) # Handle burial_in_context substructure slicing - if sel_L != dm_L and self.burial_in_context: + if sel_dm.shape != dm.shape and self.burial_in_context: self.init_index_shift = pdb_structure.init_index_shift self.fin_index_shift = pdb_structure.fin_index_shift rho_r = rho_r[self.init_index_shift:self.fin_index_shift] @@ -235,19 +196,19 @@ def _init_from_sparse_distances(self, p, sparse, expose, pdb_structure): self.rho_r = rho_r # --- Contact mask --- - contact_ci, contact_cj = frustration.compute_mask_sparse( - dm_ci, dm_cj, dm_dists, dm_L, + contact_mask = frustration.compute_mask_sparse( + dm.row, dm.col, dm.data, dm.shape, maximum_contact_distance=p.distance_cutoff_contact, minimum_sequence_separation=p.min_sequence_separation_contact, chain_breaks=self.chain_breaks) - contact_dists = self._lookup_sparse_distances(dm_ci, dm_cj, dm_dists, dm_L, contact_ci, contact_cj) + contact_dists = dm.lookup(contact_mask.row, contact_mask.col) # Theta/thetaII at contacts only theta_c = 0.25 * (1 + np.tanh(p.eta * (contact_dists - p.r_min))) * (1 + np.tanh(p.eta * (p.r_max - contact_dists))) thetaII_c = 0.25 * (1 + np.tanh(p.eta * (contact_dists - p.r_minII))) * (1 + np.tanh(p.eta * (p.r_maxII - contact_dists))) # Sigma at contact positions (no L×L allocation) - sigma_water_c = 0.25 * (1 - np.tanh(p.eta_sigma * (rho_r[contact_ci] - p.rho_0))) * (1 - np.tanh(p.eta_sigma * (rho_r[contact_cj] - p.rho_0))) + sigma_water_c = 0.25 * (1 - np.tanh(p.eta_sigma * (rho_r[contact_mask.row] - p.rho_0))) * (1 - np.tanh(p.eta_sigma * (rho_r[contact_mask.col] - p.rho_0))) sigma_protein_c = 1 - sigma_water_c # Store None for dense sigma (used in configurational frustration) @@ -270,19 +231,19 @@ def _init_from_sparse_distances(self, p, sparse, expose, pdb_structure): else: self.sequence_cutoff = p.min_sequence_separation_contact self.distance_cutoff = p.distance_cutoff_contact - mask_i, mask_j = frustration.compute_mask_sparse( - dm_ci, dm_cj, dm_dists, dm_L, + mask_result = frustration.compute_mask_sparse( + dm.row, dm.col, dm.data, dm.shape, maximum_contact_distance=self.distance_cutoff, minimum_sequence_separation=self.sequence_cutoff, chain_breaks=self.chain_breaks) - self.mask = (mask_i, mask_j, dm_L) + self.mask = mask_result # Common properties self.aa_freq = frustration.compute_aa_freq(self.sequence) self.contact_freq = frustration.compute_contact_freq(self.sequence) # Build sparse Potts model (always sparse when distance is sparse) - self._build_sparse_from_contacts(p, contact_ci, contact_cj, theta_c, thetaII_c, + self._build_sparse_from_contacts(p, contact_mask.row, contact_mask.col, theta_c, thetaII_c, sigma_water_c, sigma_protein_c, burial_energy, expose) def _init_from_dense_distances(self, p, sparse, expose, pdb_structure): @@ -541,11 +502,9 @@ def _build_sparse_from_contacts(self, p, ci, cj, theta_c, thetaII_c, # Electrostatics (from sparse 40Å distance data) if p.k_electrostatics != 0: - elec_ci, elec_cj, elec_dists, elec_L = self._sparse_distance_matrix_elec - mask_i, mask_j, mask_L = self.mask self._elec_data = frustration.build_elec_data_sparse( - elec_ci, elec_cj, elec_dists, elec_L, - mask_i, mask_j, mask_L, + self._sparse_distance_matrix_elec, + self.mask, self.sequence, self.sparse_potts_model, p.k_electrostatics, p.electrostatics_screening_length, p.min_sequence_separation_electrostatics, @@ -573,19 +532,19 @@ def _build_sparse_from_contacts(self, p, ci, cj, theta_c, thetaII_c, self.indicator_contact_j = None if p.k_electrostatics != 0: # Reconstruct dense electrostatics indicator from sparse 40Å data - elec_ci, elec_cj, elec_dists, elec_L = self._sparse_distance_matrix_elec - e_mask_ci, e_mask_cj = frustration.compute_mask_sparse( - elec_ci, elec_cj, elec_dists, elec_L, + elec_dm = self._sparse_distance_matrix_elec + e_mask = frustration.compute_mask_sparse( + elec_dm.row, elec_dm.col, elec_dm.data, elec_dm.shape, maximum_contact_distance=None, minimum_sequence_separation=p.min_sequence_separation_electrostatics, chain_breaks=self.chain_breaks) - e_dists = self._lookup_sparse_distances(elec_ci, elec_cj, elec_dists, elec_L, e_mask_ci, e_mask_cj) + e_dists = elec_dm.lookup(e_mask.row, e_mask.col) electrostatics_indicator = np.zeros((L, L)) with np.errstate(divide='ignore', invalid='ignore'): vals = np.exp(-e_dists / p.electrostatics_screening_length) / e_dists vals[np.isnan(vals)] = 0.0 vals[np.isinf(vals)] = 0.0 - electrostatics_indicator[e_mask_ci, e_mask_cj] = vals + electrostatics_indicator[e_mask.row, e_mask.col] = vals charges = np.array([0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) charges2 = charges[:, np.newaxis] * charges[np.newaxis, :] self.indicators.append(electrostatics_indicator) @@ -609,12 +568,12 @@ def _get_configurational_contact_data(self): Column indices of contacts. """ if self._distance_is_sparse: - ci, cj, dists, L = self._sparse_distance_matrix - # Upper triangle: ci < cj - upper = ci < cj - uci = ci[upper] - ucj = cj[upper] - udists = dists[upper] + dm = self._sparse_distance_matrix + # Upper triangle: row < col + upper = dm.row < dm.col + uci = dm.row[upper] + ucj = dm.col[upper] + udists = dm.data[upper] valid = (udists < self.distance_cutoff_contact) & (udists > 0) return udists[valid], uci[valid], ucj[valid] else: diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index db21322e..3d15c7ba 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -222,12 +222,12 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: if _elec_data is not None: fluctuation = frustration.apply_elec_correction_mutational(fluctuation, self.sparse_potts_model, _elec_data) elif kind == 'pseudoconfigurational': - if isinstance(self.mask, tuple): - _mi, _mj, _mL = self.mask + from ..pdb.sparse import SparseDistanceMatrix as _SDM + if isinstance(self.mask, _SDM): if self.distance_cutoff is None: - _mask_mean = frustration.mask_mean(_mL, self.sequence_cutoff, self.chain_breaks) + _mask_mean = frustration.mask_mean(self.mask.shape, self.sequence_cutoff, self.chain_breaks) else: - _mask_mean = float(len(_mi)) / (_mL * _mL) + _mask_mean = float(len(self.mask)) / (self.mask.shape * self.mask.shape) else: _mask_mean = float(self.mask.mean()) fluctuation = frustration.compute_pseudoconfigurational_decoy_energy_fluctuation_sparse(sequence, self.sparse_potts_model, _mask_mean) diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index e704d584..4d216e04 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -1,4 +1,5 @@ from .. import pdb +from ..pdb.sparse import SparseDistanceMatrix import prody import os import Bio.PDB.Polypeptide as poly @@ -93,9 +94,8 @@ def _validate_structure(self): """Check that the structure is internally consistent.""" L_seq = len(self.sequence) dm = self.distance_matrix - if isinstance(dm, tuple): - # Sparse COO: (contact_i, contact_j, distances, L) - L_dm = dm[3] + if isinstance(dm, SparseDistanceMatrix): + L_dm = dm.shape else: L_dm = dm.shape[0] if L_seq != L_dm: @@ -119,10 +119,7 @@ def distance_matrix(self): @distance_matrix.setter def distance_matrix(self, value): """Allow direct assignment for backward compatibility.""" - if isinstance(value, tuple): - assert len(value) == 4, "Sparse distance matrix must be a tuple of (contact_i, contact_j, distances, L)" - assert len(value[0]) == len(value[1]) == len(value[2]), "Sparse distance matrix contact_i, contact_j, and distances must have the same length" - assert len(value[0]) == len(self.sequence), f"Sparse distance matrix length ({len(value[0])}) does not match sequence length ({len(self.sequence)})" + if isinstance(value, SparseDistanceMatrix): self._sparse_distance_matrix = value self._dense_distance_matrix = None else: @@ -142,11 +139,9 @@ def get_dense_distance_matrix(self): return self._dense_distance_matrix @staticmethod - def _filter_sparse_tuple(sparse_tuple, init, fin): - """Filter a sparse COO tuple to a sub-range [init, fin) and re-index.""" - ci, cj, dists, L = sparse_tuple - keep = (ci >= init) & (ci < fin) & (cj >= init) & (cj < fin) - return (ci[keep] - init, cj[keep] - init, dists[keep], fin - init) + def _filter_sparse_tuple(sparse_dm, init, fin): + """Filter a SparseDistanceMatrix to a sub-range [init, fin) and re-index.""" + return sparse_dm.filter(init, fin) def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, filtered_aligned_sequence, distance_matrix_method, @@ -253,9 +248,12 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, self._sparse_distance_matrix_elec = pdb.get_sparse_distance_matrix( pdb_file=self.pdb_file, chain=self.chain, method=self.distance_matrix_method, max_distance=40.0) - ci, cj, dists, L = self._sparse_distance_matrix_elec - keep = dists <= 15.0 - self._sparse_distance_matrix = (ci[keep], cj[keep], dists[keep], L) + keep = self._sparse_distance_matrix_elec.data <= 15.0 + self._sparse_distance_matrix = SparseDistanceMatrix( + self._sparse_distance_matrix_elec.row[keep], + self._sparse_distance_matrix_elec.col[keep], + self._sparse_distance_matrix_elec.data[keep], + self._sparse_distance_matrix_elec.shape) self._dense_distance_matrix = None else: self._dense_distance_matrix = pdb.get_dense_distance_matrix( diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index eee1ba3c..4efef8dc 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -1642,11 +1642,11 @@ def compute_mask_sparse(contact_i: np.ndarray, Returns ------- - mask_i : np.ndarray - Row indices of pairs that pass the mask criteria. - mask_j : np.ndarray - Column indices of pairs that pass the mask criteria. + SparseDistanceMatrix + Mask-only (data=None) SparseDistanceMatrix of pairs that pass the criteria. """ + from frustratometer.pdb.sparse import SparseDistanceMatrix as _SDM + keep = np.ones(len(contact_i), dtype=bool) if maximum_contact_distance is not None: @@ -1661,7 +1661,7 @@ def compute_mask_sparse(contact_i: np.ndarray, pos_j = np.where(contact_j >= brk, pos_j + minimum_sequence_separation, pos_j) keep &= np.abs(pos_i - pos_j) >= minimum_sequence_separation - return contact_i[keep], contact_j[keep] + return _SDM(contact_i[keep], contact_j[keep], data=None, shape=L) def mask_mean(L: int, minimum_sequence_separation: Union[int, None] = None, chain_breaks: Union[list, None] = None): """ @@ -2363,13 +2363,8 @@ def compute_native_energy_elec(sequence: str, return energy -def build_elec_data_sparse(elec_ci: np.ndarray, - elec_cj: np.ndarray, - elec_dists: np.ndarray, - elec_L: int, - mask_i: np.ndarray, - mask_j: np.ndarray, - mask_L: int, +def build_elec_data_sparse(elec_dm, + mask_dm, sequence: str, sparse_potts_model: dict, k_electrostatics: float = 17.3636, @@ -2383,16 +2378,10 @@ def build_elec_data_sparse(elec_ci: np.ndarray, Parameters ---------- - elec_ci, elec_cj : np.ndarray - Row/col indices from the 40A sparse distance matrix. - elec_dists : np.ndarray - Distances for each (i,j) pair. - elec_L : int - Sequence length. - mask_i, mask_j : np.ndarray - Row/col indices of the frustration mask (contacts within the mask). - mask_L : int - Sequence length (should equal elec_L). + elec_dm : SparseDistanceMatrix + 40 Å sparse distance matrix for electrostatic calculations. + mask_dm : SparseDistanceMatrix + Frustration mask (data=None). sequence : str Amino acid sequence. sparse_potts_model : dict @@ -2407,8 +2396,7 @@ def build_elec_data_sparse(elec_ci: np.ndarray, Chain break positions. mask_sequence_cutoff : int, optional When provided, check sequence separation directly for mask membership - instead of using mask_i/mask_j. This avoids the mask being limited by - the sparse distance cutoff. + instead of using mask_i/mask_j. mask_chain_breaks : list, optional Chain breaks for the mask sequence separation check. @@ -2417,17 +2405,26 @@ def build_elec_data_sparse(elec_ci: np.ndarray, elec_data : dict Same keys as ``build_elec_data`` output. """ + elec_ci = elec_dm.row + elec_cj = elec_dm.col + elec_dists = elec_dm.data + elec_L = elec_dm.shape + mask_i = mask_dm.row + mask_j = mask_dm.col + seq_index = np.array([_AA.find(aa) for aa in sequence]) L = len(seq_index) charges = _CHARGES q_native = charges[seq_index] # Apply electrostatic sequence separation to full elec sparse data - filt_ci, filt_cj = compute_mask_sparse( + filt_mask = compute_mask_sparse( elec_ci, elec_cj, elec_dists, elec_L, maximum_contact_distance=None, minimum_sequence_separation=min_sequence_separation_electrostatics, chain_breaks=chain_breaks) + filt_ci = filt_mask.row + filt_cj = filt_mask.col # Build a lookup for filtered elec distances # We need the distances at (filt_ci, filt_cj) positions diff --git a/frustratometer/optimization/optimization.py b/frustratometer/optimization/optimization.py index 31db9d50..bfab6ea9 100644 --- a/frustratometer/optimization/optimization.py +++ b/frustratometer/optimization/optimization.py @@ -407,10 +407,9 @@ def __init__(self, model: Frustratometer, alphabet: str = _AA, use_numba: bool = if elec_data['indicator'] is not None: # Dense mode: indicator is (L, L) mask = model.mask - if isinstance(mask, tuple): - mask_i, mask_j, mask_L = mask - mask = np.zeros((mask_L, mask_L), dtype=float) - mask[mask_i, mask_j] = 1.0 + from frustratometer.pdb.sparse import SparseDistanceMatrix as _SDM + if isinstance(mask, _SDM): + mask = mask.to_dense(fill=0.0) self.indicator_masked = elec_data['indicator'] * mask # (L, L) else: # Sparse mode: reconstruct dense indicator_masked from sparse data diff --git a/frustratometer/pdb/__init__.py b/frustratometer/pdb/__init__.py index e8adb035..1cae8594 100644 --- a/frustratometer/pdb/__init__.py +++ b/frustratometer/pdb/__init__.py @@ -14,6 +14,7 @@ from .pdb import * from .distance import get_dense_distance_matrix, get_sparse_distance_matrix +from .sparse import SparseDistanceMatrix from .plotting import (PlotConfig, plot_distance_map, plot_interaction_map, plot_sparse_distance_map, plot_sparse_interaction_map) try: diff --git a/frustratometer/pdb/distance.py b/frustratometer/pdb/distance.py index fbe562c4..74609491 100644 --- a/frustratometer/pdb/distance.py +++ b/frustratometer/pdb/distance.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Union, Optional, Tuple +from typing import Union, Optional import numpy as np import scipy.spatial.distance as sdist @@ -7,6 +7,8 @@ import prody import itertools +from .sparse import SparseDistanceMatrix + # --------------------------------------------------------------------------- # Coordinate selection helpers (one per method) @@ -117,7 +119,7 @@ def _sparse_minimum_distance(structure, chain_selection, max_distance): pairs = tree.query_pairs(r=max_distance, output_type='ndarray') if pairs.size == 0: empty = np.array([], dtype=np.intp) - return empty, empty, np.array([], dtype=float), n_res + return SparseDistanceMatrix(empty, empty, np.array([], dtype=float), n_res) i_atoms = pairs[:, 0] j_atoms = pairs[:, 1] @@ -138,7 +140,7 @@ def _sparse_minimum_distance(structure, chain_selection, max_distance): if not min_dist: empty = np.array([], dtype=np.intp) - return empty, empty, np.array([], dtype=float), n_res + return SparseDistanceMatrix(empty, empty, np.array([], dtype=float), n_res) row_list, col_list, data_list = [], [], [] for (ri, rj), d in min_dist.items(): @@ -146,10 +148,10 @@ def _sparse_minimum_distance(structure, chain_selection, max_distance): col_list.extend([rj, ri]) data_list.extend([d, d]) - return (np.array(row_list, dtype=np.intp), - np.array(col_list, dtype=np.intp), - np.array(data_list, dtype=float), - n_res) + return SparseDistanceMatrix(np.array(row_list, dtype=np.intp), + np.array(col_list, dtype=np.intp), + np.array(data_list, dtype=float), + n_res) def _coords_to_sparse(coords, max_distance): """Calculate a sparse distance matrix from coordinates by including only pairs within max_distance.""" @@ -158,7 +160,7 @@ def _coords_to_sparse(coords, max_distance): pairs = tree.query_pairs(r=max_distance, output_type='ndarray') if pairs.size == 0: empty = np.array([], dtype=np.intp) - return empty, empty, np.array([], dtype=float), n + return SparseDistanceMatrix(empty, empty, np.array([], dtype=float), n) i_idx = pairs[:, 0] j_idx = pairs[:, 1] @@ -167,7 +169,7 @@ def _coords_to_sparse(coords, max_distance): contact_i = np.concatenate([i_idx, j_idx]).astype(np.intp) contact_j = np.concatenate([j_idx, i_idx]).astype(np.intp) data = np.concatenate([dists, dists]) - return contact_i, contact_j, data, n + return SparseDistanceMatrix(contact_i, contact_j, data, n) # --------------------------------------------------------------------------- # Public API @@ -207,7 +209,7 @@ def get_sparse_distance_matrix( chain: Optional[str], method: str, max_distance: float, -) -> Tuple[np.ndarray, np.ndarray, np.ndarray, int]: +) -> SparseDistanceMatrix: """ Calculate a sparse distance matrix of the specified atoms/residues in a PDB file. @@ -224,8 +226,8 @@ def get_sparse_distance_matrix( Returns ------- - Tuple[np.ndarray, np.ndarray, np.ndarray, int] - (contact_i, contact_j, distances, L). Both (i,j) and (j,i) stored. + SparseDistanceMatrix + Sparse distance matrix with row, col, data, shape. """ if max_distance <= 0: raise ValueError("max_distance must be > 0") diff --git a/frustratometer/pdb/plotting.py b/frustratometer/pdb/plotting.py index 1fd06c7e..1cf12f86 100644 --- a/frustratometer/pdb/plotting.py +++ b/frustratometer/pdb/plotting.py @@ -60,11 +60,8 @@ def _resolve_config(config: Optional[PlotConfig], **kwargs) -> PlotConfig: def _sparse_to_dense(sparse_dm) -> np.ndarray: - """Convert a COO tuple ``(i, j, dist, L)`` to an L×L array with NaN gaps.""" - ci, cj, dists, L = sparse_dm - mat = np.full((L, L), np.nan) - mat[ci, cj] = dists - return mat + """Convert a SparseDistanceMatrix to an L×L array with NaN gaps.""" + return sparse_dm.to_dense(fill=np.nan) def _setup_ax(ax, L: int, title: str): diff --git a/frustratometer/pdb/sparse.py b/frustratometer/pdb/sparse.py new file mode 100644 index 00000000..74030c0d --- /dev/null +++ b/frustratometer/pdb/sparse.py @@ -0,0 +1,135 @@ +"""Sparse distance matrix stored in COO format.""" + +import numpy as np + +__all__ = ['SparseDistanceMatrix'] + + +class SparseDistanceMatrix: + """Coordinate-format (COO) sparse distance matrix. + + Stores only non-zero (i, j, distance) triples for residue pairs within a + distance cutoff. When used as a mask (no distances), *data* is ``None``. + + Parameters + ---------- + row : np.ndarray (N,) + Row indices. + col : np.ndarray (N,) + Column indices. + data : np.ndarray (N,) or None + Distance values. ``None`` for mask-only matrices. + shape : int or None + Sequence length L. Inferred from ``max(row, col) + 1`` when *None*. + """ + + __slots__ = ('row', 'col', 'data', 'shape', '_sort_idx') + + def __init__(self, row, col, data=None, shape=None): + self.row = np.asarray(row, dtype=np.intp) + self.col = np.asarray(col, dtype=np.intp) + self.data = np.asarray(data, dtype=float) if data is not None else None + if shape is None: + if len(self.row) == 0: + shape = 0 + else: + shape = int(max(self.row.max(), self.col.max())) + 1 + self.shape = int(shape) + self._sort_idx = None # lazy-cached argsort for lookup + + # ------------------------------------------------------------------ + # Lookup + # ------------------------------------------------------------------ + def lookup(self, query_i, query_j): + """Look up distances at specific (i, j) positions via binary search. + + Equivalent to ``dense_matrix[query_i, query_j]`` without materialising + the full L×L matrix. + + Every queried pair **must** already exist in (row, col). + """ + if self.data is None: + raise ValueError("Cannot lookup distances on a mask (data is None).") + if self._sort_idx is None: + src_key = self.row.astype(np.int64) * self.shape + self.col.astype(np.int64) + self._sort_idx = np.argsort(src_key) + src_key = self.row.astype(np.int64) * self.shape + self.col.astype(np.int64) + qry_key = np.asarray(query_i, dtype=np.int64) * self.shape + np.asarray(query_j, dtype=np.int64) + pos = np.searchsorted(src_key, qry_key, sorter=self._sort_idx) + return self.data[self._sort_idx[pos]] + + # ------------------------------------------------------------------ + # Mask computation + # ------------------------------------------------------------------ + def compute_mask(self, maximum_contact_distance=None, + minimum_sequence_separation=None, chain_breaks=None): + """Return a mask-only SparseDistanceMatrix (data=None) of passing pairs. + + Parameters + ---------- + maximum_contact_distance : float or None + Keep pairs with distance <= this value. + minimum_sequence_separation : int or None + Keep pairs with |i - j| >= this value. + chain_breaks : list of int or None + Cross-chain pairs always satisfy sequence separation. + """ + keep = np.ones(len(self.row), dtype=bool) + + if maximum_contact_distance is not None: + if self.data is None: + raise ValueError("Cannot filter by distance on a mask (data is None).") + keep &= self.data <= maximum_contact_distance + + if minimum_sequence_separation is not None: + pos_i = self.row.astype(np.float64) + pos_j = self.col.astype(np.float64) + if chain_breaks is not None: + for brk in chain_breaks: + pos_i = np.where(self.row >= brk, pos_i + minimum_sequence_separation, pos_i) + pos_j = np.where(self.col >= brk, pos_j + minimum_sequence_separation, pos_j) + keep &= np.abs(pos_i - pos_j) >= minimum_sequence_separation + + return SparseDistanceMatrix(self.row[keep], self.col[keep], + data=None, shape=self.shape) + + # ------------------------------------------------------------------ + # Filtering / slicing + # ------------------------------------------------------------------ + def filter(self, init, fin): + """Return a new SparseDistanceMatrix restricted to [init, fin) and re-indexed.""" + keep = (self.row >= init) & (self.row < fin) & (self.col >= init) & (self.col < fin) + new_data = self.data[keep] if self.data is not None else None + return SparseDistanceMatrix(self.row[keep] - init, self.col[keep] - init, + data=new_data, shape=fin - init) + + # ------------------------------------------------------------------ + # Dense reconstruction + # ------------------------------------------------------------------ + def to_dense(self, fill=np.inf): + """Reconstruct an L×L dense array. + + Parameters + ---------- + fill : float + Value for entries not stored. Default ``np.inf``. + Diagonal is always 0.0. For masks (data=None), stored pairs get 1.0. + """ + L = self.shape + mat = np.full((L, L), fill, dtype=float) + np.fill_diagonal(mat, 0.0) + if self.data is not None: + mat[self.row, self.col] = self.data + else: + mat[self.row, self.col] = 1.0 + return mat + + # ------------------------------------------------------------------ + # Dunder methods + # ------------------------------------------------------------------ + def __len__(self): + return len(self.row) + + def __repr__(self): + kind = 'mask' if self.data is None else 'distance' + return f"SparseDistanceMatrix({kind}, nnz={len(self)}, L={self.shape})" diff --git a/tests/test_sparse_distance.py b/tests/test_sparse_distance.py index f0ccdacf..b6add557 100644 --- a/tests/test_sparse_distance.py +++ b/tests/test_sparse_distance.py @@ -3,6 +3,7 @@ import pytest from pathlib import Path from frustratometer.pdb.distance import get_dense_distance_matrix, get_sparse_distance_matrix +from frustratometer.pdb.sparse import SparseDistanceMatrix PDB_FILE = Path(__file__).parent / "data" / "6u5e.pdb" CHAIN = "A" @@ -23,12 +24,13 @@ def test_sparse_is_lossless_subset_of_full(method): """Reconstructing a dense matrix from sparse entries must equal the full matrix everywhere within the cutoff (and zero elsewhere).""" full = get_dense_distance_matrix(PDB_FILE, CHAIN, method=method) - ci, cj, d, L = get_sparse_distance_matrix(PDB_FILE, CHAIN, method, MAX_DISTANCE) - assert L == full.shape[0] + sdm = get_sparse_distance_matrix(PDB_FILE, CHAIN, method, MAX_DISTANCE) + assert isinstance(sdm, SparseDistanceMatrix) + assert sdm.shape == full.shape[0] # Reconstruct dense from sparse - reconstructed = np.zeros((L, L)) - reconstructed[ci, cj] = d + reconstructed = np.zeros((sdm.shape, sdm.shape)) + reconstructed[sdm.row, sdm.col] = sdm.data # Where full <= cutoff and off-diagonal, reconstructed must match mask = (full > 0) & (full <= MAX_DISTANCE) @@ -39,12 +41,12 @@ def test_sparse_is_lossless_subset_of_full(method): def test_sparse_cutoff_respected(): """Tighter cutoff produces fewer entries, all within bound.""" - ci_w, _, d_wide, _ = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 15.0) - ci_n, _, d_narrow, _ = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 8.0) - assert len(d_narrow) < len(d_wide) - assert d_narrow.max() <= 8.0 - assert d_wide.max() <= 15.0 - assert d_wide.max() > 8.0 + sdm_wide = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 15.0) + sdm_narrow = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 8.0) + assert len(sdm_narrow) < len(sdm_wide) + assert sdm_narrow.data.max() <= 8.0 + assert sdm_wide.data.max() <= 15.0 + assert sdm_wide.data.max() > 8.0 def test_structure_sparse_flag(): @@ -52,8 +54,8 @@ def test_structure_sparse_flag(): import frustratometer s_on = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=True) assert s_on._sparse_distance_matrix is not None - ci, cj, d, L = s_on._sparse_distance_matrix - assert L == len(s_on.sequence) + assert isinstance(s_on._sparse_distance_matrix, SparseDistanceMatrix) + assert s_on._sparse_distance_matrix.shape == len(s_on.sequence) s_off = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=False) assert s_off._sparse_distance_matrix is None diff --git a/tests/test_sparse_potts.py b/tests/test_sparse_potts.py index ccd353c1..2f0992a5 100644 --- a/tests/test_sparse_potts.py +++ b/tests/test_sparse_potts.py @@ -49,10 +49,10 @@ def test_sparse_mask_matches_dense(small_system, max_dist, min_sep, chain_breaks L, Q, dm, ci, cj, cd, _ = small_system dense_mask = compute_mask(dm, max_dist, min_sep, chain_breaks=chain_breaks) - sparse_i, sparse_j = compute_mask_sparse(ci, cj, cd, L, max_dist, min_sep, chain_breaks=chain_breaks) + sparse_mask = compute_mask_sparse(ci, cj, cd, L, max_dist, min_sep, chain_breaks=chain_breaks) reconstructed = np.zeros((L, L), dtype=bool) - reconstructed[sparse_i, sparse_j] = True + reconstructed[sparse_mask.row, sparse_mask.col] = True off_diag = ~np.eye(L, dtype=bool) np.testing.assert_array_equal(reconstructed[off_diag], dense_mask[off_diag]) diff --git a/tests/test_structure.py b/tests/test_structure.py index 8eb4db10..5628279c 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -6,6 +6,7 @@ import pytest from pathlib import Path import frustratometer +from frustratometer.pdb.sparse import SparseDistanceMatrix test_data_path = Path(__file__).parent / 'data' @@ -22,7 +23,7 @@ def test_structure_valid(pdb, chain, repair_pdb, expect_repair, tmp_path): s = frustratometer.Structure(test_data_path / pdb, chain, repair_pdb=repair_pdb, pdb_directory=tmp_path) dm = s.distance_matrix - L = dm[3] if isinstance(dm, tuple) else dm.shape[0] + L = dm.shape if isinstance(dm, SparseDistanceMatrix) else dm.shape[0] assert len(s.sequence) == L cleaned_files = list(tmp_path.glob("*_cleaned.pdb")) was_repaired = len(cleaned_files) > 0 @@ -54,7 +55,7 @@ def test_from_pdb_list(repair_pdb, tmp_path): assert len(structures) == 2 for s in structures: dm = s.distance_matrix - L = dm[3] if isinstance(dm, tuple) else dm.shape[0] + L = dm.shape if isinstance(dm, SparseDistanceMatrix) else dm.shape[0] assert len(s.sequence) == L From 477641c0ae219848f836fd18e30c42708abd009b Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 13 Apr 2026 15:54:02 -0500 Subject: [PATCH 18/28] Fixes tests --- tests/test_awsem_frustratometer.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index 5baaece7..867af37a 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -755,8 +755,7 @@ def test_sparse_dense_chain_breaks_preserved(): assert dense_m.chain_breaks == [57] # In sparse mode, mask only covers pairs in the sparse distance matrix. # Verify that every sparse mask pair is also in the dense mask. - mask_i, mask_j, mask_L = sparse_m.mask - assert np.all(dense_m.mask[mask_i, mask_j]) + assert np.all(dense_m.mask[sparse_m.mask.row, sparse_m.mask.col]) def test_sparse_dense_multichain_elec_energy(): From 9c825e94566821a3e1017e5400e2b179d4c10239 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 13 Apr 2026 16:36:32 -0500 Subject: [PATCH 19/28] Fixes sparse matrix import test --- tests/test_sparse_distance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_sparse_distance.py b/tests/test_sparse_distance.py index b6add557..e149ad92 100644 --- a/tests/test_sparse_distance.py +++ b/tests/test_sparse_distance.py @@ -52,9 +52,10 @@ def test_sparse_cutoff_respected(): def test_structure_sparse_flag(): """sparse=True populates _sparse_distance_matrix; False leaves it None.""" import frustratometer + from frustratometer.pdb.sparse import SparseDistanceMatrix as _SDM s_on = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=True) assert s_on._sparse_distance_matrix is not None - assert isinstance(s_on._sparse_distance_matrix, SparseDistanceMatrix) + assert isinstance(s_on._sparse_distance_matrix, _SDM) assert s_on._sparse_distance_matrix.shape == len(s_on.sequence) s_off = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=False) From b926f9ededf78a07deb493d0dd49f6ee77353b6b Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Mon, 13 Apr 2026 19:44:31 -0500 Subject: [PATCH 20/28] Separate class for sparse matrices --- frustratometer/classes/AWSEM.py | 4 +- frustratometer/classes/Frustratometer.py | 4 +- frustratometer/classes/Structure.py | 106 ++++++- frustratometer/classes/__init__.py | 4 +- frustratometer/frustration/frustration.py | 12 +- frustratometer/optimization/optimization.py | 4 +- frustratometer/pdb/__init__.py | 4 +- frustratometer/pdb/distance.py | 27 +- frustratometer/pdb/plotting.py | 5 +- frustratometer/pdb/sparse.py | 288 +++++++++++--------- tests/test_sparse_distance.py | 27 +- tests/test_structure.py | 6 +- 12 files changed, 311 insertions(+), 180 deletions(-) diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index 3df37c53..9f70c3dc 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -1,7 +1,7 @@ import numpy as np from ..utils import _path from .. import frustration -from ..pdb.sparse import SparseDistanceMatrix +from .Structure import SparseMatrix from .Frustratometer import Frustratometer from .Gamma import Gamma from pydantic import BaseModel, Field, ConfigDict @@ -167,7 +167,7 @@ def _init_from_sparse_distances(self, p, sparse, expose, pdb_structure): # --- Rho computation --- if self.burial_in_context: full_dm = self.full_pdb_distance_matrix - if isinstance(full_dm, SparseDistanceMatrix): + if isinstance(full_dm, SparseMatrix): sel_dm = full_dm else: # Full PDB is dense but selection is sparse — fallback diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index 3d15c7ba..b441fd01 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -222,8 +222,8 @@ def decoy_fluctuation(self, sequence:str = None,kind:str = 'singleresidue',mask: if _elec_data is not None: fluctuation = frustration.apply_elec_correction_mutational(fluctuation, self.sparse_potts_model, _elec_data) elif kind == 'pseudoconfigurational': - from ..pdb.sparse import SparseDistanceMatrix as _SDM - if isinstance(self.mask, _SDM): + from .Structure import SparseMatrix as _SM + if isinstance(self.mask, _SM): if self.distance_cutoff is None: _mask_mean = frustration.mask_mean(self.mask.shape, self.sequence_cutoff, self.chain_breaks) else: diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index 4d216e04..7f084551 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -1,5 +1,6 @@ from .. import pdb -from ..pdb.sparse import SparseDistanceMatrix +from ..pdb.sparse import (sparse_lookup, sparse_compute_mask, + sparse_filter, sparse_to_dense) import prody import os import Bio.PDB.Polypeptide as poly @@ -10,12 +11,98 @@ import logging import warnings -__all__ = ['Structure'] +__all__ = ['Structure', 'SparseMatrix'] logger = logging.getLogger(__name__) residue_names=[] + +class SparseMatrix: + """COO sparse matrix wrapping the functional API in ``pdb.sparse``. + + Stores ``(row, col, data)`` arrays and a scalar *shape* (sequence length L). + When used as a mask (no distances), *data* is ``None``. + + Parameters + ---------- + row : array-like (N,) + Row indices. + col : array-like (N,) + Column indices. + data : array-like (N,) or None + Distance values. ``None`` for mask-only matrices. + shape : int or None + Sequence length L. Inferred from ``max(row, col) + 1`` when *None*. + """ + + __slots__ = ('row', 'col', 'data', 'shape') + + def __init__(self, row, col, data=None, shape=None): + self.row = np.asarray(row, dtype=np.intp) + self.col = np.asarray(col, dtype=np.intp) + self.data = np.asarray(data, dtype=float) if data is not None else None + if shape is None: + if len(self.row) == 0: + shape = 0 + else: + shape = int(max(self.row.max(), self.col.max())) + 1 + self.shape = int(shape) + + # ------------------------------------------------------------------ + # Lookup + # ------------------------------------------------------------------ + def lookup(self, query_i, query_j): + """Look up distances at ``(query_i, query_j)`` via binary search.""" + return sparse_lookup(self.row, self.col, self.data, self.shape, + query_i, query_j) + + # ------------------------------------------------------------------ + # Mask computation + # ------------------------------------------------------------------ + def compute_mask(self, maximum_contact_distance=None, + minimum_sequence_separation=None, chain_breaks=None): + """Return a mask-only ``SparseMatrix`` (data=None) of passing pairs.""" + mr, mc, ms = sparse_compute_mask( + self.row, self.col, self.data, self.shape, + maximum_contact_distance=maximum_contact_distance, + minimum_sequence_separation=minimum_sequence_separation, + chain_breaks=chain_breaks) + return SparseMatrix(mr, mc, data=None, shape=ms) + + # ------------------------------------------------------------------ + # Filtering / slicing + # ------------------------------------------------------------------ + def filter(self, init, fin): + """Return a new ``SparseMatrix`` restricted to ``[init, fin)`` and re-indexed.""" + nr, nc, nd, ns = sparse_filter( + self.row, self.col, self.data, self.shape, init, fin) + return SparseMatrix(nr, nc, nd, ns) + + # ------------------------------------------------------------------ + # Dense reconstruction + # ------------------------------------------------------------------ + def to_dense(self, fill=np.inf): + """Reconstruct an L×L dense array. + + Parameters + ---------- + fill : float + Value for entries not stored. Default ``np.inf``. + Diagonal is always 0.0. For masks, stored pairs get 1.0. + """ + return sparse_to_dense(self.row, self.col, self.data, self.shape, fill) + + # ------------------------------------------------------------------ + # Dunder methods + # ------------------------------------------------------------------ + def __len__(self): + return len(self.row) + + def __repr__(self): + kind = 'mask' if self.data is None else 'distance' + return f"SparseMatrix({kind}, nnz={len(self)}, L={self.shape})" + class Structure: def __init__(self, pdb_file: Union[Path,str], chain: Union[str,None]=None, seq_selection: str = None, aligned_sequence: str = None, filtered_aligned_sequence: str = None, @@ -94,7 +181,7 @@ def _validate_structure(self): """Check that the structure is internally consistent.""" L_seq = len(self.sequence) dm = self.distance_matrix - if isinstance(dm, SparseDistanceMatrix): + if isinstance(dm, SparseMatrix): L_dm = dm.shape else: L_dm = dm.shape[0] @@ -119,7 +206,7 @@ def distance_matrix(self): @distance_matrix.setter def distance_matrix(self, value): """Allow direct assignment for backward compatibility.""" - if isinstance(value, SparseDistanceMatrix): + if isinstance(value, SparseMatrix): self._sparse_distance_matrix = value self._dense_distance_matrix = None else: @@ -140,7 +227,7 @@ def get_dense_distance_matrix(self): @staticmethod def _filter_sparse_tuple(sparse_dm, init, fin): - """Filter a SparseDistanceMatrix to a sub-range [init, fin) and re-index.""" + """Filter a SparseMatrix to a sub-range [init, fin) and re-index.""" return sparse_dm.filter(init, fin) def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, @@ -245,11 +332,12 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, if sparse: # Compute the less stringent sparse matrix for electrostatic calculations (max_distance=40.0) # then filter it down for the main sparse matrix (max_distance=15.0) - self._sparse_distance_matrix_elec = pdb.get_sparse_distance_matrix( - pdb_file=self.pdb_file, chain=self.chain, - method=self.distance_matrix_method, max_distance=40.0) + self._sparse_distance_matrix_elec = SparseMatrix( + *pdb.get_sparse_distance_matrix( + pdb_file=self.pdb_file, chain=self.chain, + method=self.distance_matrix_method, max_distance=40.0)) keep = self._sparse_distance_matrix_elec.data <= 15.0 - self._sparse_distance_matrix = SparseDistanceMatrix( + self._sparse_distance_matrix = SparseMatrix( self._sparse_distance_matrix_elec.row[keep], self._sparse_distance_matrix_elec.col[keep], self._sparse_distance_matrix_elec.data[keep], diff --git a/frustratometer/classes/__init__.py b/frustratometer/classes/__init__.py index 6621727b..ed3d7874 100644 --- a/frustratometer/classes/__init__.py +++ b/frustratometer/classes/__init__.py @@ -8,10 +8,10 @@ from .DCA import DCA from .AWSEM import AWSEM -from .Structure import Structure +from .Structure import Structure, SparseMatrix from .Map import Map from .Gamma import Gamma -__all__ = ['DCA', 'AWSEM', 'Structure', 'Map', 'Gamma'] +__all__ = ['DCA', 'AWSEM', 'Structure', 'SparseMatrix', 'Map', 'Gamma'] # __all__.extend(DCA.__all__) # __all__.extend(AWSEM.__all__) diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index 4efef8dc..c00e6f0e 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -1642,10 +1642,10 @@ def compute_mask_sparse(contact_i: np.ndarray, Returns ------- - SparseDistanceMatrix - Mask-only (data=None) SparseDistanceMatrix of pairs that pass the criteria. + SparseMatrix + Mask-only (data=None) SparseMatrix of pairs that pass the criteria. """ - from frustratometer.pdb.sparse import SparseDistanceMatrix as _SDM + from frustratometer.classes.Structure import SparseMatrix as _SM keep = np.ones(len(contact_i), dtype=bool) @@ -1661,7 +1661,7 @@ def compute_mask_sparse(contact_i: np.ndarray, pos_j = np.where(contact_j >= brk, pos_j + minimum_sequence_separation, pos_j) keep &= np.abs(pos_i - pos_j) >= minimum_sequence_separation - return _SDM(contact_i[keep], contact_j[keep], data=None, shape=L) + return _SM(contact_i[keep], contact_j[keep], data=None, shape=L) def mask_mean(L: int, minimum_sequence_separation: Union[int, None] = None, chain_breaks: Union[list, None] = None): """ @@ -2378,9 +2378,9 @@ def build_elec_data_sparse(elec_dm, Parameters ---------- - elec_dm : SparseDistanceMatrix + elec_dm : SparseMatrix 40 Å sparse distance matrix for electrostatic calculations. - mask_dm : SparseDistanceMatrix + mask_dm : SparseMatrix Frustration mask (data=None). sequence : str Amino acid sequence. diff --git a/frustratometer/optimization/optimization.py b/frustratometer/optimization/optimization.py index bfab6ea9..0e963b11 100644 --- a/frustratometer/optimization/optimization.py +++ b/frustratometer/optimization/optimization.py @@ -407,8 +407,8 @@ def __init__(self, model: Frustratometer, alphabet: str = _AA, use_numba: bool = if elec_data['indicator'] is not None: # Dense mode: indicator is (L, L) mask = model.mask - from frustratometer.pdb.sparse import SparseDistanceMatrix as _SDM - if isinstance(mask, _SDM): + from frustratometer.classes.Structure import SparseMatrix as _SM + if isinstance(mask, _SM): mask = mask.to_dense(fill=0.0) self.indicator_masked = elec_data['indicator'] * mask # (L, L) else: diff --git a/frustratometer/pdb/__init__.py b/frustratometer/pdb/__init__.py index 1cae8594..db08eaf7 100644 --- a/frustratometer/pdb/__init__.py +++ b/frustratometer/pdb/__init__.py @@ -14,7 +14,8 @@ from .pdb import * from .distance import get_dense_distance_matrix, get_sparse_distance_matrix -from .sparse import SparseDistanceMatrix +from .sparse import (sparse_lookup, sparse_compute_mask, + sparse_filter, sparse_to_dense) from .plotting import (PlotConfig, plot_distance_map, plot_interaction_map, plot_sparse_distance_map, plot_sparse_interaction_map) try: @@ -39,5 +40,6 @@ def warn_pdbfixer_not_installed(): __all__ = ['download', 'get_sequence', 'get_dense_distance_matrix', 'get_sparse_distance_matrix', 'full_to_filtered_aligned_mapping', 'repair_pdb', 'repair_pdbs', + 'sparse_lookup', 'sparse_compute_mask', 'sparse_filter', 'sparse_to_dense', 'PlotConfig', 'plot_distance_map', 'plot_interaction_map', 'plot_sparse_distance_map', 'plot_sparse_interaction_map'] \ No newline at end of file diff --git a/frustratometer/pdb/distance.py b/frustratometer/pdb/distance.py index 74609491..7a538304 100644 --- a/frustratometer/pdb/distance.py +++ b/frustratometer/pdb/distance.py @@ -7,8 +7,6 @@ import prody import itertools -from .sparse import SparseDistanceMatrix - # --------------------------------------------------------------------------- # Coordinate selection helpers (one per method) @@ -119,7 +117,7 @@ def _sparse_minimum_distance(structure, chain_selection, max_distance): pairs = tree.query_pairs(r=max_distance, output_type='ndarray') if pairs.size == 0: empty = np.array([], dtype=np.intp) - return SparseDistanceMatrix(empty, empty, np.array([], dtype=float), n_res) + return (empty, empty, np.array([], dtype=float), n_res) i_atoms = pairs[:, 0] j_atoms = pairs[:, 1] @@ -140,7 +138,7 @@ def _sparse_minimum_distance(structure, chain_selection, max_distance): if not min_dist: empty = np.array([], dtype=np.intp) - return SparseDistanceMatrix(empty, empty, np.array([], dtype=float), n_res) + return (empty, empty, np.array([], dtype=float), n_res) row_list, col_list, data_list = [], [], [] for (ri, rj), d in min_dist.items(): @@ -148,10 +146,10 @@ def _sparse_minimum_distance(structure, chain_selection, max_distance): col_list.extend([rj, ri]) data_list.extend([d, d]) - return SparseDistanceMatrix(np.array(row_list, dtype=np.intp), - np.array(col_list, dtype=np.intp), - np.array(data_list, dtype=float), - n_res) + return (np.array(row_list, dtype=np.intp), + np.array(col_list, dtype=np.intp), + np.array(data_list, dtype=float), + n_res) def _coords_to_sparse(coords, max_distance): """Calculate a sparse distance matrix from coordinates by including only pairs within max_distance.""" @@ -160,7 +158,7 @@ def _coords_to_sparse(coords, max_distance): pairs = tree.query_pairs(r=max_distance, output_type='ndarray') if pairs.size == 0: empty = np.array([], dtype=np.intp) - return SparseDistanceMatrix(empty, empty, np.array([], dtype=float), n) + return (empty, empty, np.array([], dtype=float), n) i_idx = pairs[:, 0] j_idx = pairs[:, 1] @@ -169,7 +167,7 @@ def _coords_to_sparse(coords, max_distance): contact_i = np.concatenate([i_idx, j_idx]).astype(np.intp) contact_j = np.concatenate([j_idx, i_idx]).astype(np.intp) data = np.concatenate([dists, dists]) - return SparseDistanceMatrix(contact_i, contact_j, data, n) + return (contact_i, contact_j, data, n) # --------------------------------------------------------------------------- # Public API @@ -209,7 +207,7 @@ def get_sparse_distance_matrix( chain: Optional[str], method: str, max_distance: float, -) -> SparseDistanceMatrix: +) -> tuple: """ Calculate a sparse distance matrix of the specified atoms/residues in a PDB file. @@ -226,8 +224,11 @@ def get_sparse_distance_matrix( Returns ------- - SparseDistanceMatrix - Sparse distance matrix with row, col, data, shape. + tuple of (row, col, data, shape) + row : np.ndarray (N,) – row indices. + col : np.ndarray (N,) – column indices. + data : np.ndarray (N,) – distances. + shape : int – sequence length. """ if max_distance <= 0: raise ValueError("max_distance must be > 0") diff --git a/frustratometer/pdb/plotting.py b/frustratometer/pdb/plotting.py index 1cf12f86..d351480f 100644 --- a/frustratometer/pdb/plotting.py +++ b/frustratometer/pdb/plotting.py @@ -60,8 +60,9 @@ def _resolve_config(config: Optional[PlotConfig], **kwargs) -> PlotConfig: def _sparse_to_dense(sparse_dm) -> np.ndarray: - """Convert a SparseDistanceMatrix to an L×L array with NaN gaps.""" - return sparse_dm.to_dense(fill=np.nan) + """Convert a SparseMatrix (or duck-typed object with row/col/data/shape) to an L×L array with NaN gaps.""" + from .sparse import sparse_to_dense + return sparse_to_dense(sparse_dm.row, sparse_dm.col, sparse_dm.data, sparse_dm.shape, fill=np.nan) def _setup_ax(ax, L: int, title: str): diff --git a/frustratometer/pdb/sparse.py b/frustratometer/pdb/sparse.py index 74030c0d..58bfeb08 100644 --- a/frustratometer/pdb/sparse.py +++ b/frustratometer/pdb/sparse.py @@ -1,135 +1,175 @@ -"""Sparse distance matrix stored in COO format.""" +"""Sparse COO utilities — functional API for sparse distance / mask arrays. + +All functions operate on plain NumPy arrays (row, col, data, shape) so users +who prefer a purely functional workflow never need to instantiate a class. +The OOP wrapper :class:`~frustratometer.classes.Structure.SparseMatrix` in +``Structure.py`` delegates to these functions. +""" import numpy as np -__all__ = ['SparseDistanceMatrix'] +__all__ = [ + 'sparse_lookup', + 'sparse_compute_mask', + 'sparse_filter', + 'sparse_to_dense', +] + +# ------------------------------------------------------------------ +# Lookup +# ------------------------------------------------------------------ +def sparse_lookup(row, col, data, shape, query_i, query_j): + """Binary-search lookup of distances at specific ``(query_i, query_j)`` positions. -class SparseDistanceMatrix: - """Coordinate-format (COO) sparse distance matrix. + Equivalent to ``dense_matrix[query_i, query_j]`` without materialising + the full L×L matrix. Every queried pair **must** already exist in + ``(row, col)``. - Stores only non-zero (i, j, distance) triples for residue pairs within a - distance cutoff. When used as a mask (no distances), *data* is ``None``. + Parameters + ---------- + row, col : array-like (N,) + Stored coordinate indices. + data : array-like (N,) + Distance values. Must not be *None*. + shape : int + Sequence length *L*. + query_i, query_j : array-like + Positions to look up. + + Returns + ------- + np.ndarray + Distances at the queried positions. + """ + if data is None: + raise ValueError("Cannot lookup distances on mask data (data is None).") + row = np.asarray(row, dtype=np.int64) + col = np.asarray(col, dtype=np.int64) + data = np.asarray(data, dtype=float) + src_key = row * shape + col + sort_idx = np.argsort(src_key) + qry_key = np.asarray(query_i, dtype=np.int64) * shape + np.asarray(query_j, dtype=np.int64) + pos = np.searchsorted(src_key, qry_key, sorter=sort_idx) + return data[sort_idx[pos]] + + +# ------------------------------------------------------------------ +# Mask computation +# ------------------------------------------------------------------ +def sparse_compute_mask(row, col, data, shape, + maximum_contact_distance=None, + minimum_sequence_separation=None, + chain_breaks=None): + """Return indices of pairs passing distance / sequence-separation criteria. Parameters ---------- - row : np.ndarray (N,) - Row indices. - col : np.ndarray (N,) - Column indices. - data : np.ndarray (N,) or None - Distance values. ``None`` for mask-only matrices. - shape : int or None - Sequence length L. Inferred from ``max(row, col) + 1`` when *None*. + row, col : array-like (N,) + Stored coordinate indices. + data : array-like (N,) or None + Distance values. Required when *maximum_contact_distance* is set. + shape : int + Sequence length *L*. + maximum_contact_distance : float, optional + Keep pairs with distance ≤ this value. + minimum_sequence_separation : int, optional + Keep pairs with ``|i − j| ≥`` this value. + chain_breaks : list of int, optional + Cross-chain pairs always satisfy sequence separation. + + Returns + ------- + mask_row : np.ndarray + Row indices of accepted pairs. + mask_col : np.ndarray + Column indices of accepted pairs. + shape : int + Unchanged sequence length (passed through for convenience). """ + row = np.asarray(row, dtype=np.intp) + col = np.asarray(col, dtype=np.intp) + keep = np.ones(len(row), dtype=bool) + + if maximum_contact_distance is not None: + if data is None: + raise ValueError("Cannot filter by distance on mask data (data is None).") + keep &= np.asarray(data, dtype=float) <= maximum_contact_distance + + if minimum_sequence_separation is not None: + pos_i = row.astype(np.float64) + pos_j = col.astype(np.float64) + if chain_breaks is not None: + for brk in chain_breaks: + pos_i = np.where(row >= brk, pos_i + minimum_sequence_separation, pos_i) + pos_j = np.where(col >= brk, pos_j + minimum_sequence_separation, pos_j) + keep &= np.abs(pos_i - pos_j) >= minimum_sequence_separation + + return row[keep], col[keep], int(shape) + + +# ------------------------------------------------------------------ +# Filtering / slicing +# ------------------------------------------------------------------ +def sparse_filter(row, col, data, shape, init, fin): + """Restrict to entries in ``[init, fin)`` and re-index to zero. - __slots__ = ('row', 'col', 'data', 'shape', '_sort_idx') - - def __init__(self, row, col, data=None, shape=None): - self.row = np.asarray(row, dtype=np.intp) - self.col = np.asarray(col, dtype=np.intp) - self.data = np.asarray(data, dtype=float) if data is not None else None - if shape is None: - if len(self.row) == 0: - shape = 0 - else: - shape = int(max(self.row.max(), self.col.max())) + 1 - self.shape = int(shape) - self._sort_idx = None # lazy-cached argsort for lookup - - # ------------------------------------------------------------------ - # Lookup - # ------------------------------------------------------------------ - def lookup(self, query_i, query_j): - """Look up distances at specific (i, j) positions via binary search. - - Equivalent to ``dense_matrix[query_i, query_j]`` without materialising - the full L×L matrix. - - Every queried pair **must** already exist in (row, col). - """ - if self.data is None: - raise ValueError("Cannot lookup distances on a mask (data is None).") - if self._sort_idx is None: - src_key = self.row.astype(np.int64) * self.shape + self.col.astype(np.int64) - self._sort_idx = np.argsort(src_key) - src_key = self.row.astype(np.int64) * self.shape + self.col.astype(np.int64) - qry_key = np.asarray(query_i, dtype=np.int64) * self.shape + np.asarray(query_j, dtype=np.int64) - pos = np.searchsorted(src_key, qry_key, sorter=self._sort_idx) - return self.data[self._sort_idx[pos]] - - # ------------------------------------------------------------------ - # Mask computation - # ------------------------------------------------------------------ - def compute_mask(self, maximum_contact_distance=None, - minimum_sequence_separation=None, chain_breaks=None): - """Return a mask-only SparseDistanceMatrix (data=None) of passing pairs. - - Parameters - ---------- - maximum_contact_distance : float or None - Keep pairs with distance <= this value. - minimum_sequence_separation : int or None - Keep pairs with |i - j| >= this value. - chain_breaks : list of int or None - Cross-chain pairs always satisfy sequence separation. - """ - keep = np.ones(len(self.row), dtype=bool) - - if maximum_contact_distance is not None: - if self.data is None: - raise ValueError("Cannot filter by distance on a mask (data is None).") - keep &= self.data <= maximum_contact_distance - - if minimum_sequence_separation is not None: - pos_i = self.row.astype(np.float64) - pos_j = self.col.astype(np.float64) - if chain_breaks is not None: - for brk in chain_breaks: - pos_i = np.where(self.row >= brk, pos_i + minimum_sequence_separation, pos_i) - pos_j = np.where(self.col >= brk, pos_j + minimum_sequence_separation, pos_j) - keep &= np.abs(pos_i - pos_j) >= minimum_sequence_separation - - return SparseDistanceMatrix(self.row[keep], self.col[keep], - data=None, shape=self.shape) - - # ------------------------------------------------------------------ - # Filtering / slicing - # ------------------------------------------------------------------ - def filter(self, init, fin): - """Return a new SparseDistanceMatrix restricted to [init, fin) and re-indexed.""" - keep = (self.row >= init) & (self.row < fin) & (self.col >= init) & (self.col < fin) - new_data = self.data[keep] if self.data is not None else None - return SparseDistanceMatrix(self.row[keep] - init, self.col[keep] - init, - data=new_data, shape=fin - init) - - # ------------------------------------------------------------------ - # Dense reconstruction - # ------------------------------------------------------------------ - def to_dense(self, fill=np.inf): - """Reconstruct an L×L dense array. - - Parameters - ---------- - fill : float - Value for entries not stored. Default ``np.inf``. - Diagonal is always 0.0. For masks (data=None), stored pairs get 1.0. - """ - L = self.shape - mat = np.full((L, L), fill, dtype=float) - np.fill_diagonal(mat, 0.0) - if self.data is not None: - mat[self.row, self.col] = self.data - else: - mat[self.row, self.col] = 1.0 - return mat - - # ------------------------------------------------------------------ - # Dunder methods - # ------------------------------------------------------------------ - def __len__(self): - return len(self.row) - - def __repr__(self): - kind = 'mask' if self.data is None else 'distance' - return f"SparseDistanceMatrix({kind}, nnz={len(self)}, L={self.shape})" + Parameters + ---------- + row, col : array-like (N,) + Stored coordinate indices. + data : array-like (N,) or None + Distance values. + shape : int + Original sequence length. + init, fin : int + Half-open range to keep. + + Returns + ------- + new_row, new_col : np.ndarray + Re-indexed indices. + new_data : np.ndarray or None + Filtered distances (or *None* if input was *None*). + new_shape : int + ``fin − init``. + """ + row = np.asarray(row, dtype=np.intp) + col = np.asarray(col, dtype=np.intp) + keep = (row >= init) & (row < fin) & (col >= init) & (col < fin) + new_data = np.asarray(data, dtype=float)[keep] if data is not None else None + return row[keep] - init, col[keep] - init, new_data, fin - init + + +# ------------------------------------------------------------------ +# Dense reconstruction +# ------------------------------------------------------------------ +def sparse_to_dense(row, col, data, shape, fill=np.inf): + """Reconstruct an L×L dense array from COO arrays. + + Parameters + ---------- + row, col : array-like (N,) + Stored coordinate indices. + data : array-like (N,) or None + Distance values. If *None*, stored pairs are set to 1.0 (mask mode). + shape : int + Sequence length *L*. + fill : float + Value for entries not stored. Default ``np.inf``. + Diagonal is always 0.0. + + Returns + ------- + np.ndarray (L, L) + """ + L = int(shape) + mat = np.full((L, L), fill, dtype=float) + np.fill_diagonal(mat, 0.0) + row = np.asarray(row, dtype=np.intp) + col = np.asarray(col, dtype=np.intp) + if data is not None: + mat[row, col] = np.asarray(data, dtype=float) + else: + mat[row, col] = 1.0 + return mat diff --git a/tests/test_sparse_distance.py b/tests/test_sparse_distance.py index e149ad92..3a3c7083 100644 --- a/tests/test_sparse_distance.py +++ b/tests/test_sparse_distance.py @@ -3,7 +3,6 @@ import pytest from pathlib import Path from frustratometer.pdb.distance import get_dense_distance_matrix, get_sparse_distance_matrix -from frustratometer.pdb.sparse import SparseDistanceMatrix PDB_FILE = Path(__file__).parent / "data" / "6u5e.pdb" CHAIN = "A" @@ -24,13 +23,13 @@ def test_sparse_is_lossless_subset_of_full(method): """Reconstructing a dense matrix from sparse entries must equal the full matrix everywhere within the cutoff (and zero elsewhere).""" full = get_dense_distance_matrix(PDB_FILE, CHAIN, method=method) - sdm = get_sparse_distance_matrix(PDB_FILE, CHAIN, method, MAX_DISTANCE) - assert isinstance(sdm, SparseDistanceMatrix) - assert sdm.shape == full.shape[0] + row, col, data, shape = get_sparse_distance_matrix(PDB_FILE, CHAIN, method, MAX_DISTANCE) + assert isinstance(row, np.ndarray) + assert shape == full.shape[0] # Reconstruct dense from sparse - reconstructed = np.zeros((sdm.shape, sdm.shape)) - reconstructed[sdm.row, sdm.col] = sdm.data + reconstructed = np.zeros((shape, shape)) + reconstructed[row, col] = data # Where full <= cutoff and off-diagonal, reconstructed must match mask = (full > 0) & (full <= MAX_DISTANCE) @@ -41,21 +40,21 @@ def test_sparse_is_lossless_subset_of_full(method): def test_sparse_cutoff_respected(): """Tighter cutoff produces fewer entries, all within bound.""" - sdm_wide = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 15.0) - sdm_narrow = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 8.0) - assert len(sdm_narrow) < len(sdm_wide) - assert sdm_narrow.data.max() <= 8.0 - assert sdm_wide.data.max() <= 15.0 - assert sdm_wide.data.max() > 8.0 + _, _, data_wide, _ = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 15.0) + row_narrow, _, data_narrow, _ = get_sparse_distance_matrix(PDB_FILE, CHAIN, "CB", 8.0) + assert len(data_narrow) < len(data_wide) + assert data_narrow.max() <= 8.0 + assert data_wide.max() <= 15.0 + assert data_wide.max() > 8.0 def test_structure_sparse_flag(): """sparse=True populates _sparse_distance_matrix; False leaves it None.""" import frustratometer - from frustratometer.pdb.sparse import SparseDistanceMatrix as _SDM + from frustratometer.classes.Structure import SparseMatrix as _SM s_on = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=True) assert s_on._sparse_distance_matrix is not None - assert isinstance(s_on._sparse_distance_matrix, _SDM) + assert isinstance(s_on._sparse_distance_matrix, _SM) assert s_on._sparse_distance_matrix.shape == len(s_on.sequence) s_off = frustratometer.Structure(PDB_FILE, CHAIN, repair_pdb=False, sparse=False) diff --git a/tests/test_structure.py b/tests/test_structure.py index 5628279c..b20f4271 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -6,7 +6,7 @@ import pytest from pathlib import Path import frustratometer -from frustratometer.pdb.sparse import SparseDistanceMatrix +from frustratometer.classes.Structure import SparseMatrix test_data_path = Path(__file__).parent / 'data' @@ -23,7 +23,7 @@ def test_structure_valid(pdb, chain, repair_pdb, expect_repair, tmp_path): s = frustratometer.Structure(test_data_path / pdb, chain, repair_pdb=repair_pdb, pdb_directory=tmp_path) dm = s.distance_matrix - L = dm.shape if isinstance(dm, SparseDistanceMatrix) else dm.shape[0] + L = dm.shape if isinstance(dm, SparseMatrix) else dm.shape[0] assert len(s.sequence) == L cleaned_files = list(tmp_path.glob("*_cleaned.pdb")) was_repaired = len(cleaned_files) > 0 @@ -55,7 +55,7 @@ def test_from_pdb_list(repair_pdb, tmp_path): assert len(structures) == 2 for s in structures: dm = s.distance_matrix - L = dm.shape if isinstance(dm, SparseDistanceMatrix) else dm.shape[0] + L = dm.shape if isinstance(dm, SparseMatrix) else dm.shape[0] assert len(s.sequence) == L From 5f421b6283aede8c5356a6433cf8314b67aeb85c Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 08:42:51 -0500 Subject: [PATCH 21/28] Adds sparse distance matrix support for dca --- frustratometer/classes/DCA.py | 35 ++++++++++++++++++++++++----- frustratometer/classes/Structure.py | 6 ++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frustratometer/classes/DCA.py b/frustratometer/classes/DCA.py index dc279686..d869e970 100644 --- a/frustratometer/classes/DCA.py +++ b/frustratometer/classes/DCA.py @@ -46,6 +46,7 @@ def __init__(self): self.mapped_distance_matrix = None self.distance_matrix = None self.chain_breaks = None + self._structure_sparse_dm = None self.mask = None self.minimally_frustrated_threshold = 1 self.aa_freq = None @@ -115,6 +116,31 @@ def _init_attributes(self, pdb_structure, sequence_cutoff, distance_cutoff): self.mapped_distance_matrix = pdb_structure.mapped_distance_matrix self.distance_matrix = self.mapped_distance_matrix self.chain_breaks = getattr(pdb_structure, 'chain_breaks', None) + # Store both sparse DMs: _elec has the wider radius, _sparse is capped at 15 Å + self._structure_sparse_dm = getattr(pdb_structure, '_sparse_distance_matrix', None) + self._structure_sparse_dm_elec = getattr(pdb_structure, '_sparse_distance_matrix_elec', None) + + def _compute_mask(self, distance_cutoff=None, sequence_cutoff=None, chain_breaks=None): + """Compute a dense boolean mask, handling the sparse-structure case.""" + from .Structure import SparseMatrix + dm = self.mapped_distance_matrix + if dm is None and self._structure_sparse_dm is not None: + # Use the wider-radius elec sparse DM when available so that + # distance cutoffs > 15 Å are handled correctly. + sparse_dm = self._structure_sparse_dm_elec or self._structure_sparse_dm + sparse_mask = sparse_dm.compute_mask( + maximum_contact_distance=distance_cutoff, + minimum_sequence_separation=sequence_cutoff, + chain_breaks=chain_breaks) + mask = sparse_mask.to_dense(fill=0).astype(np.bool_) + # The sparse DM doesn't store diagonal entries (distance=0). + # The dense path includes diagonal when distance_cutoff is None + # or >= 0, so replicate that behavior here. + if distance_cutoff is None or distance_cutoff >= 0: + if sequence_cutoff is None or sequence_cutoff <= 0: + np.fill_diagonal(mask, True) + return mask + return frustration.compute_mask(dm, distance_cutoff, sequence_cutoff, chain_breaks=chain_breaks) def _init_from_alignment(self, pdb_structure, alignment_output_file_name, filtered_alignment_output_file_name, DCA_format, @@ -124,8 +150,7 @@ def _init_from_alignment(self, pdb_structure, alignment_output_file_name, self.alignment_output_file_name = alignment_output_file_name self.filtered_alignment_output_file_name = filtered_alignment_output_file_name self.DCA_format = DCA_format - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, - self.sequence_cutoff, chain_breaks=self.chain_breaks) + self.mask = self._compute_mask(self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) def _finalize_from_alignment(self, sparse): """Compute Potts model from alignment and apply sparse storage.""" @@ -263,7 +288,7 @@ def from_pottsmodel(cls,pdb_structure : object, example_matrix=np.ones((len(self.filtered_aligned_sequence),len(self.filtered_aligned_sequence))) self.mask = frustration.compute_mask(example_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) else: - self.mask = frustration.compute_mask(self.mapped_distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) + self.mask = self._compute_mask(self.distance_cutoff, self.sequence_cutoff, chain_breaks=self.chain_breaks) self._reformat_potts_model(potts_model) self._apply_sparse_potts_model(potts_model, sparse) @@ -475,8 +500,8 @@ def sequence_cutoff(self): @sequence_cutoff.setter def sequence_cutoff(self, value): - self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._sequence_cutoff = value + self.mask = self._compute_mask(self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._native_energy = None self._decoy_fluctuation = {} @@ -486,8 +511,8 @@ def distance_cutoff(self): @distance_cutoff.setter def distance_cutoff(self, value): - self.mask = frustration.compute_mask(self.distance_matrix, self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._distance_cutoff = value + self.mask = self._compute_mask(self.distance_cutoff, self.sequence_cutoff, chain_breaks=getattr(self, 'chain_breaks', None)) self._native_energy = None self._decoy_fluctuation = {} diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index a543c957..684643cb 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -379,9 +379,9 @@ def _init_structure(self, pdb_file, chain, seq_selection, aligned_sequence, if self.aligned_sequence is not None: if self._is_sparse: - raise NotImplementedError( - "aligned_sequence is not supported with sparse distance matrices. " - "Use sparse=False or call get_dense_distance_matrix() first.") + # aligned_sequence mapping requires a dense distance matrix; + # reconstruct it from the pdb + self.get_dense_distance_matrix() self.full_to_aligned_index_dict=pdb.full_to_filtered_aligned_mapping(self.aligned_sequence,self.filtered_aligned_sequence) self.mapped_distance_matrix=np.full((len(self.filtered_aligned_sequence), len(self.filtered_aligned_sequence)), np.inf) pos1, pos2 = np.meshgrid(list(self.full_to_aligned_index_dict.keys()), list(self.full_to_aligned_index_dict.keys()), From 5f571ecc091ead2aff555909ecaad005662a23ab Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 11:17:02 -0500 Subject: [PATCH 22/28] Adds action to update README in forks --- .github/workflows/update-readme.yml | 82 +++++++++++++++++++++++++++++ README.md | 9 ++-- 2 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/update-readme.yml diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml new file mode 100644 index 00000000..abbef874 --- /dev/null +++ b/.github/workflows/update-readme.yml @@ -0,0 +1,82 @@ +name: Update README badges + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: write + +jobs: + update-badges: + if: github.actor != 'github-actions[bot]' + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Rewrite badge block in README + env: + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + run: | + python3 <<'PY' + import os + from pathlib import Path + + readme = Path("README.md") + text = readme.read_text() + + start = "" + end = "" + + if start not in text or end not in text: + raise SystemExit("README.md is missing badge markers") + + owner = os.environ["OWNER"] + repo = os.environ["REPO"] + + badge_block = ( + f"\n" + f"[![GitHub Actions Build Status](https://github.com/{owner}/{repo}/workflows/CI/badge.svg)]" + f"(https://github.com/{owner}/{repo}/actions?query=workflow%3ACI)\n" + f"[![codecov](https://codecov.io/gh/{owner}/{repo}/graph/badge.svg?token=JKDOXOYPRS)]" + f"(https://codecov.io/gh/{owner}/{repo})\n" + f"[![Documentation Status](https://readthedocs.org/projects/frustratometer/badge/?version=latest)]" + f"(https://frustratometer.readthedocs.io/en/latest/?badge=latest)\n" + f"" + ) + + before, rest = text.split(start, 1) + _, after = rest.split(end, 1) + new_text = before + badge_block + after + + # Rewrite clone URL + clone_start = "" + clone_end = "" + if clone_start in new_text and clone_end in new_text: + clone_block = ( + f"\n" + f" git clone https://github.com/{owner}/{repo}\n" + f"" + ) + cb, crest = new_text.split(clone_start, 1) + _, cafter = crest.split(clone_end, 1) + new_text = cb + clone_block + cafter + + if new_text != text: + readme.write_text(new_text) + print("README updated.") + else: + print("README already up to date.") + PY + + - name: Commit changes if needed + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add README.md + git diff --cached --quiet || git commit -m "Update README badges for ${{ github.repository }}" + git diff --cached --quiet || git push diff --git a/README.md b/README.md index b7a1e3b0..49b047b0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ Frustratometer ============================== -[//]: # (Badges) + [![GitHub Actions Build Status](https://github.com/cabb99/Frustratometer/workflows/CI/badge.svg)](https://github.com/cabb99/Frustratometer/actions?query=workflow%3ACI) -[![codecov](https://codecov.io/gh/HanaJaafari/Frustratometer/graph/badge.svg?token=JKDOXOYPRS)](https://codecov.io/gh/HanaJaafari/Frustratometer) +[![codecov](https://codecov.io/gh/cabb99/Frustratometer/graph/badge.svg?token=JKDOXOYPRS)](https://codecov.io/gh/cabb99/Frustratometer) [![Documentation Status](https://readthedocs.org/projects/frustratometer/badge/?version=latest)](https://frustratometer.readthedocs.io/en/latest/?badge=latest) + @@ -39,7 +40,9 @@ Note: `openmm` and `pdbfixer` are not available on PyPI and must be installed se ### From source - git clone https://github.com/HanaJaafari/Frustratometer + + git clone https://github.com/cabb99/Frustratometer + cd Frustratometer conda install -c conda-forge --file requirements.txt pip install -e . From 05aa804d59b71e61db8bc292519ec1d14995dcf0 Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 12:19:11 -0500 Subject: [PATCH 23/28] Update docstring for profiling utilities --- devtools/profiling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/profiling.py b/devtools/profiling.py index 78b60196..ac5ac9a1 100644 --- a/devtools/profiling.py +++ b/devtools/profiling.py @@ -1,5 +1,5 @@ """ -Simple profiling utilities for tracking memory usage and execution time. +Profiling utilities for tracking memory usage and execution time. Usage: from devtools.profiling import track_time, track_memory, profile From b3857eb7fb52056ab0d1a69afadd6b52171dd0af Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 13:43:02 -0500 Subject: [PATCH 24/28] Updates documentation --- devtools/profiling.py | 2 +- docs/api_classes.rst | 12 +++- docs/examples_awsem.rst | 14 ++++- docs/examples_dca.rst | 8 +++ docs/frustratometer.rst | 2 +- docs/sparse.rst | 17 +++++- frustratometer/align/align.py | 13 ++--- frustratometer/classes/Structure.py | 8 +-- frustratometer/frustration/frustration.py | 68 +++++++++++------------ frustratometer/pdb/plotting.py | 8 +-- tests/test_awsem_frustratometer.py | 2 +- tests/test_gamma.py | 2 +- tests/test_sparse_potts.py | 4 +- tests/test_structure.py | 14 ++--- 14 files changed, 108 insertions(+), 66 deletions(-) diff --git a/devtools/profiling.py b/devtools/profiling.py index ac5ac9a1..ee35cd80 100644 --- a/devtools/profiling.py +++ b/devtools/profiling.py @@ -1,7 +1,7 @@ """ Profiling utilities for tracking memory usage and execution time. -Usage: +Usage (from the project folder) from devtools.profiling import track_time, track_memory, profile # Context managers diff --git a/docs/api_classes.rst b/docs/api_classes.rst index c85b654a..021a74dc 100644 --- a/docs/api_classes.rst +++ b/docs/api_classes.rst @@ -33,7 +33,7 @@ The frustratometer package provides a handful of classes used to encapsulate the :inherited-members: :private-members: -.. autoclass:: Frustratometer +.. autoclass:: frustratometer.classes.Frustratometer.Frustratometer :members: :undoc-members: :member-order: bysource @@ -49,4 +49,14 @@ The frustratometer package provides a handful of classes used to encapsulate the :inherited-members: :private-members: +.. autoclass:: SparseMatrix + :members: + :undoc-members: + :member-order: bysource + :show-inheritance: +.. autoclass:: Gamma + :members: + :undoc-members: + :member-order: bysource + :show-inheritance: \ No newline at end of file diff --git a/docs/examples_awsem.rst b/docs/examples_awsem.rst index 86eb97e4..048dae98 100644 --- a/docs/examples_awsem.rst +++ b/docs/examples_awsem.rst @@ -9,18 +9,30 @@ The Frustratometer package includes a prody-based Structure class to load the st .. code-block:: python import frustratometer + from pathlib import Path # Define the path to your PDB file pdb_path = Path('data/my_protein.pdb') - # Load the structure + # Load the structure (dense distance matrix) structure = frustratometer.Structure.full_pdb(pdb_path) structure.sequence #The sequence of the structure +For large proteins you can use a sparse distance matrix to avoid allocating the +full :math:`(L, L)` array: + +.. code-block:: python + + structure_sparse = frustratometer.Structure.full_pdb(pdb_path, sparse=True) + Creating an AWSEM Model Instance ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ After loading the structure, create an AWSEM model instance with the desired parameters. Here we provide some typical configurations that can be found elsewhere. +The AWSEM constructor defaults to ``sparse=True``, building a sparse Potts model +that stores couplings only at contact positions. Pass ``sparse=False`` to build +the full dense representation. + .. code-block:: python ## Single residue frustration with electrostatics diff --git a/docs/examples_dca.rst b/docs/examples_dca.rst index 08d5966e..7ec57b65 100644 --- a/docs/examples_dca.rst +++ b/docs/examples_dca.rst @@ -9,6 +9,7 @@ The Frustratometer package includes a prody-based Structure class to load the st .. code-block:: python import frustratometer + from pathlib import Path # Define the path to your PDB file pdb_path = Path('data/my_protein.pdb') @@ -23,7 +24,13 @@ After loading the structure, create a DCA model instance with the desired parame When using Potts Model files generated by the mfDCA algorithm, make sure to set the "reformat_potts_model" to True. +All DCA factory methods default to ``sparse=True``, which stores couplings only +at contact positions to avoid allocating the full :math:`(N, N, 21, 21)` tensor. +Pass ``sparse=False`` if you need the dense representation (e.g. for contact +prediction via ``scores()``). + .. code-block:: python + potts_model_file=Path('data/my_potts_model.mat') ## Using existing potts model file @@ -36,6 +43,7 @@ Check the Accuracy of the Potts Model In order to check the accuracy of the contacts predicted by the Potts model and true contacts from the protein's contact map, the receiver operator curve (ROC) can be generated. If the Potts model has high accuracy, the Area Under the Curve (AUC) of the ROC will be 1. .. code-block:: python + ## Generate the ROC curve model_dca.plot_roc() diff --git a/docs/frustratometer.rst b/docs/frustratometer.rst index 107f1a82..52cd2271 100644 --- a/docs/frustratometer.rst +++ b/docs/frustratometer.rst @@ -27,7 +27,7 @@ In this module, we implement a version of the frustratometer based on Direct Cou Copyright --------- -Copyright (c) 2022-2024, Carlos Bueno, Hana Jaafari +Copyright (c) 2022-2026, Carlos Bueno, Hana Jaafari Acknowledgements ---------------- diff --git a/docs/sparse.rst b/docs/sparse.rst index f4cd0dee..fefa2b64 100644 --- a/docs/sparse.rst +++ b/docs/sparse.rst @@ -8,6 +8,13 @@ can provide a more straight-forward view of the interactions, but it is computat The sparse framework avoids this by storing only the couplings at positions where the contact mask is nonzero — typically a small fraction of all pairs. +.. note:: + + Sparse mode is now the **default** for both ``AWSEM`` and ``DCA`` classes + (``sparse=True``). The ``Structure`` class also supports sparse distance + matrices via ``sparse=True``, which avoids allocating the full + :math:`(L, L)` distance matrix. + Sparse Potts Model ------------------ @@ -40,10 +47,14 @@ decoy fluctuations), a CSR-like lookup structure groups contacts by position: Sparse Mask ^^^^^^^^^^^ -Computes the mask without materializing a full :math:`(L, L)` matrix: +Computes the mask without creating a full :math:`(L, L)` matrix. +Returns a :class:`~frustratometer.classes.Structure.SparseMatrix` (mask-only, +``data=None``) instead of a dense boolean array. .. autofunction:: frustratometer.frustration.frustration.compute_mask_sparse +.. autofunction:: frustratometer.frustration.frustration.mask_mean + Sparse Energy Functions ----------------------- @@ -162,6 +173,8 @@ by all correction functions. .. autofunction:: frustratometer.frustration.frustration.build_elec_data +.. autofunction:: frustratometer.frustration.frustration.build_elec_data_sparse + Native energy correction ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,6 +194,8 @@ The factor of :math:`\tfrac{1}{2}` avoids double-counting the symmetric .. autofunction:: frustratometer.frustration.frustration.compute_native_energy_elec +.. autofunction:: frustratometer.frustration.frustration.compute_native_energy_elec_sparse + Decoy corrections ^^^^^^^^^^^^^^^^^ diff --git a/frustratometer/align/align.py b/frustratometer/align/align.py index 7f4733b5..9fe8ec48 100644 --- a/frustratometer/align/align.py +++ b/frustratometer/align/align.py @@ -24,15 +24,14 @@ def jackhmmer(sequence: str, Databases can be downloaded from: https://www.uniprot.org/help/downloads log: File handle Path to write the output of the program. Default:DEVNULL - dry_run: bool (default: False) + dry_run : bool (default: False) Creates a fasta file with the sequence and prints the command needed to run jackhmmer - **kwargs: + **kwargs Other arguments that can be passed to jackhmmer. - More information can be found by executing `jackhmmer -h` - arguments without a value such as --noali should be passed as `noali=True` - Common kwargs: - N: number of iterations - E: E-value threshold + More information can be found by executing ``jackhmmer -h``. + Arguments without a value such as ``--noali`` should be passed as ``noali=True``. + Common kwargs: ``N`` (number of iterations), ``E`` (E-value threshold). + Returns ------- output_file: Path diff --git a/frustratometer/classes/Structure.py b/frustratometer/classes/Structure.py index 684643cb..64bd3908 100644 --- a/frustratometer/classes/Structure.py +++ b/frustratometer/classes/Structure.py @@ -412,9 +412,9 @@ def from_pdb_list(cls, pdb_files, chain=None, pdb_directory=None, repair_pdb=Non pdb_directory : Path, optional Directory for repaired files. repair_pdb : bool or None - True → repair all in parallel, then build. - False → build all without repair. - None (default) → build without repair first; batch-repair + True -> repair all in parallel, then build. + False -> build all without repair. + None (default) -> build without repair first; batch-repair only the ones that fail validation, then rebuild those. **kwargs Extra keyword arguments passed to each Structure(). @@ -484,7 +484,7 @@ def plot_distance_map(self, interaction_type: bool = False, config=None, interaction_type : bool If True, colour contacts by interaction band. config : PlotConfig, optional - Visual settings. Fields can also be overridden via **kwargs. + Visual settings. Fields can also be overridden via ``**kwargs``. ax : matplotlib Axes, optional Axes to draw on. **kwargs diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index c00e6f0e..d28b92bf 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -41,8 +41,8 @@ def compute_mask(distance_matrix: np.array, The maximum distance of a contact. Include i,j if distance_matrix[i,j] <= maximum_contact_distance. If None, no distance filtering is applied. Default is None. minimum_sequence_separation : int, optional - A minimum sequence separation threshold. Include i,j if |i-j| >= minimum_sequence_separation. - If None, no sequence separation is applied . Default is None. + A minimum sequence separation threshold. Include i,j if ``abs(i-j) >= minimum_sequence_separation``. + If None, no sequence separation is applied. Default is None. chain_breaks : list of int, optional Indices where new chains begin (excluding the implicit 0). For example, [50, 80] means three chains: residues 0-49, 50-79, 80-end. Cross-chain pairs always satisfy @@ -1137,20 +1137,19 @@ def compute_fragment_mask(mask: np.array, Creates a mask for a sequence fragment such that: - position i belongs to the fragment, all j - position j belongs to the fragment, all i - + The new mask consider all the interactions within the fragment and also the interactions between the fragment and other sequence positions. - + Parameters ---------- - mask : np.array - A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. - fragment_pos: np:array - Array of sequence positions selected. - - Return + A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. + fragment_pos : np.array + Array of sequence positions selected. + + Returns ------- - fragment_mask: np.array + fragment_mask : np.array New 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. """ @@ -1167,9 +1166,8 @@ def compute_fragment_total_native_energy(seq: str, mask: np.array, fragment_pos : Union[None, np.array] = None, fragment_in_context = False ) -> float: - """ - Calculates the energy for the complete protein or for a fragment in context + Calculates the energy for the complete protein or for a fragment in context. Parameters ---------- @@ -1179,15 +1177,15 @@ def compute_fragment_total_native_energy(seq: str, A dictionary containing the Potts model parameters 'h' (fields) and 'J' (couplings). The fields are a 2D array of shape (L, 20), where L is the length of the sequence and 20 is the number of amino acids. The couplings are a 4D array of shape (L, L, 20, 20). The fields and couplings are assumed to be in units of energy. mask : np.array A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. - fragment_pos: np:array + fragment_pos : np.array Array of sequence positions selected. - fragment_in_context: bool - If True, the energetics calculations take into account the interactions between the fragment and other sequence positions - - Return + fragment_in_context : bool + If True, the energetics calculations take into account the interactions between the fragment and other sequence positions. + + Returns ------- - energy: float - Native energy of the protein + energy : float + Native energy of the protein. """ @@ -1229,7 +1227,7 @@ def compute_fragment_total_decoy_energy(decoy_seqs: list, config_decoys = False, msa_mask = 1) -> np.array: """ - Calculates decoy energies for the complete protein or for a fragment in context + Calculates decoy energies for the complete protein or for a fragment in context. Parameters ---------- @@ -1239,21 +1237,21 @@ def compute_fragment_total_decoy_energy(decoy_seqs: list, A dictionary containing the Potts model parameters 'h' (fields) and 'J' (couplings). The fields are a 2D array of shape (L, 20), where L is the length of the sequence and 20 is the number of amino acids. The couplings are a 4D array of shape (L, L, 20, 20). The fields and couplings are assumed to be in units of energy. mask : np.array A 2D Boolean array that determines which residue pairs should be considered in the energy computation. The mask should have dimensions (L, L), where L is the length of the sequence. - fragment_pos: np:array + fragment_pos : np.array Array of sequence positions selected. - fragment_in_context: bool - If True, the energetics calculations take into account the interactions between the fragment and other sequence positions - split_couplings_and_fields: bool + fragment_in_context : bool + If True, the energetics calculations take into account the interactions between the fragment and other sequence positions. + split_couplings_and_fields : bool Separate output into coupling and local fields contribution to energy. - config_decoys: bool + config_decoys : bool If True, use the pseudoconfigurational decoys approximation, shuffling index positions for pseudoconfigurational decoys energy calculation. If False, mutational decoys. - msa_mask: np.array - Extra mask to use a Multiple Sequence Alignment that do not cover completely the reference PDB - - Return + msa_mask : np.array + Extra mask to use a Multiple Sequence Alignment that do not cover completely the reference PDB. + + Returns ------- - energy: np.array - Decoy energies + energy : np.array + Decoy energies. """ seq_index = np.array([[_AA.find(aa) for aa in seq] for seq in decoy_seqs]) @@ -1635,7 +1633,7 @@ def compute_mask_sparse(contact_i: np.ndarray, maximum_contact_distance : float, optional Include pair if distance <= this value. If None, no distance filtering. minimum_sequence_separation : int, optional - Include pair if |i - j| >= this value. If None, no sequence separation filtering. + Include pair if ``abs(i - j) >= this value``. If None, no sequence separation filtering. chain_breaks : list of int, optional Indices where new chains begin (excluding the implicit 0). Cross-chain pairs always satisfy the minimum sequence separation. Default is None. @@ -1676,8 +1674,8 @@ def mask_mean(L: int, minimum_sequence_separation: Union[int, None] = None, chai L : int The number of residues (sequence length). The full mask would have shape (L, L). minimum_sequence_separation : int, optional - Minimum sequence separation |i - j| required for a pair to be included. - Pairs with |i - j| < minimum_sequence_separation are excluded. + Minimum sequence separation ``abs(i - j)`` required for a pair to be included. + Pairs with ``abs(i - j) < minimum_sequence_separation`` are excluded. If None, no sequence-separation filtering is applied and 1.0 is returned. Default is None. chain_breaks : list of int, optional diff --git a/frustratometer/pdb/plotting.py b/frustratometer/pdb/plotting.py index ce9c40be..fb74c45a 100644 --- a/frustratometer/pdb/plotting.py +++ b/frustratometer/pdb/plotting.py @@ -4,8 +4,8 @@ - ``plot_distance_map`` – dense L×L, continuous 0-to-vmax colourmap - ``plot_interaction_map`` – dense L×L, categorical band colours -- ``plot_sparse_distance_map`` – sparse COO → temporary L×L with NaN gaps -- ``plot_sparse_interaction_map`` – sparse COO → temporary L×L with NaN gaps +- ``plot_sparse_distance_map`` – sparse COO -> temporary L×L with NaN gaps +- ``plot_sparse_interaction_map`` – sparse COO -> temporary L×L with NaN gaps All accept an optional ``PlotConfig`` (pydantic) for visual settings. Any config field can also be overridden as a keyword argument. @@ -118,7 +118,7 @@ def plot_distance_map( ax: Optional[plt.Axes] = None, **kwargs, ) -> plt.Axes: - """Plot a dense distance matrix with a continuous colourmap (0 → vmax).""" + """Plot a dense distance matrix with a continuous colourmap (0 -> vmax).""" cfg = _resolve_config(config, **kwargs) if ax is None: @@ -157,7 +157,7 @@ def plot_interaction_map( # --------------------------------------------------------------------------- -# Public API – sparse (COO → imshow with NaN for missing) +# Public API – sparse (COO -> imshow with NaN for missing) # --------------------------------------------------------------------------- def plot_sparse_distance_map( diff --git a/tests/test_awsem_frustratometer.py b/tests/test_awsem_frustratometer.py index 867af37a..fd1f694a 100644 --- a/tests/test_awsem_frustratometer.py +++ b/tests/test_awsem_frustratometer.py @@ -542,7 +542,7 @@ def test_sparse_frustration_matches_dense(kind, awsem_6u5e_density, sparse_6u5e_ # Dense frustration from cached decoys (no recomputation) dense_frust = compute_pair_frustration(dense_decoys_6u5e_density[kind], model.contact_freq) - # Sparse pipeline: decoy → frustration → densify + # Sparse pipeline: decoy -> frustration -> densify sparse_func = (compute_mutational_decoy_energy_fluctuation_sparse if kind == 'mutational' else compute_contact_decoy_energy_fluctuation_sparse) sparse_decoy = sparse_func(model.sequence, spm) diff --git a/tests/test_gamma.py b/tests/test_gamma.py index ea617fb1..0a8e4340 100644 --- a/tests/test_gamma.py +++ b/tests/test_gamma.py @@ -414,7 +414,7 @@ def test_correlate_with_incompatible_instances(self): class TestGammaFileIO(unittest.TestCase): def setUp(self): - # Simple setup for file I/O tests + # Setup for file I/O tests self.segment_definition = {'Segment': (1, 5)} self.gamma = frustratometer.Gamma(np.arange(5), self.segment_definition) self.temp_file_path = "gamma_test_file.json" diff --git a/tests/test_sparse_potts.py b/tests/test_sparse_potts.py index 2f0992a5..b15cf15e 100644 --- a/tests/test_sparse_potts.py +++ b/tests/test_sparse_potts.py @@ -70,7 +70,7 @@ def test_sparse_mask_matches_dense(small_system, max_dist, min_sep, chain_breaks def test_sparse_potts_roundtrip_and_lookup(small_system): - """dense→sparse→dense recovers J at contacts; lookup indexes them correctly.""" + """dense->sparse->dense recovers J at contacts; lookup indexes them correctly.""" L, Q, dm, _, _, _, potts_model = small_system mask = compute_mask(dm, maximum_contact_distance=10.0, minimum_sequence_separation=3) @@ -115,6 +115,6 @@ def test_structure_detects_chain_breaks(): pytest.skip("5msm.cif not available") s = Structure(cif_path, chain=None) - # 5msm has 6 chains (A,B,C,D,E,F) → 5 break points + # 5msm has 6 chains (A,B,C,D,E,F) -> 5 break points assert s.chain_breaks is not None assert len(s.chain_breaks) == 5 diff --git a/tests/test_structure.py b/tests/test_structure.py index b20f4271..747c3c3d 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -12,11 +12,11 @@ @pytest.mark.parametrize("pdb,chain,repair_pdb,expect_repair", [ - ("6u5e.pdb", "A", None, False), # complete, auto-detect → no repair needed - ("6u5e.pdb", "A", False, False), # complete, skip repair → fine - ("6u5e.pdb", "A", True, True), # complete, force repair → calls pdbfixer - ("2GHY.pdb", "A", None, True), # incomplete, auto-detect → repairs automatically - ("2GHY.pdb", "A", True, True), # incomplete, force repair → calls pdbfixer + ("6u5e.pdb", "A", None, False), # complete, auto-detect -> no repair needed + ("6u5e.pdb", "A", False, False), # complete, skip repair -> fine + ("6u5e.pdb", "A", True, True), # complete, force repair -> calls pdbfixer + ("2GHY.pdb", "A", None, True), # incomplete, auto-detect -> repairs automatically + ("2GHY.pdb", "A", True, True), # incomplete, force repair -> calls pdbfixer ]) def test_structure_valid(pdb, chain, repair_pdb, expect_repair, tmp_path): """Structure should be consistent and only call PDBFixer when expected.""" @@ -43,7 +43,7 @@ def test_from_pdb_list(repair_pdb, tmp_path): """Load multiple PDBs via from_pdb_list with different repair modes.""" pdb_files = [test_data_path / '6u5e.pdb', test_data_path / '2GHY.pdb'] if repair_pdb is False: - # 2GHY is incomplete → False should fail + # 2GHY is incomplete -> False should fail with pytest.raises(ValueError, match="repair_pdb=True"): frustratometer.Structure.from_pdb_list(pdb_files, 'A', pdb_directory=tmp_path, @@ -130,6 +130,6 @@ def test_structure_detects_chain_breaks(): pytest.skip("5msm.cif not available") s = frustratometer.Structure(cif_path, chain=None) - # 5msm has 6 chains (A,B,C,D,E,F) → 5 break points + # 5msm has 6 chains (A,B,C,D,E,F) -> 5 break points assert s.chain_breaks is not None assert len(s.chain_breaks) == 5 \ No newline at end of file From fe1d9501f4729afca8cac0d6b082eee4fdb7488d Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 19:11:23 -0500 Subject: [PATCH 25/28] Lazy import in optimization to save 20s of numba compilation --- frustratometer/optimization/__init__.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/frustratometer/optimization/__init__.py b/frustratometer/optimization/__init__.py index a18a079e..b8ca786c 100644 --- a/frustratometer/optimization/__init__.py +++ b/frustratometer/optimization/__init__.py @@ -1,2 +1,15 @@ -from .optimization import * -from .inner_product import build_mean_inner_product_matrix, permutation_numpy_inner_product \ No newline at end of file +def __getattr__(name): + import importlib + _opt = importlib.import_module(".optimization", __name__) + _ip = importlib.import_module(".inner_product", __name__) + + _ns = {} + for _mod in (_opt, _ip): + for _k in dir(_mod): + if not _k.startswith("_"): + _ns[_k] = getattr(_mod, _k) + globals().update(_ns) + + if name in _ns: + return _ns[name] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") \ No newline at end of file From 663e13ce8cab274199f918373f1f168c88ce3fed Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 19:11:46 -0500 Subject: [PATCH 26/28] Fixes visualization script for multiple chains --- frustratometer/frustration/frustration.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index d28b92bf..ad2f650e 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -933,13 +933,13 @@ def write_tcl_script(pdb_file: Union[Path,str], chain: str, mask: np.array, dist structure = prody.parsePDB(str(pdb_file)) selection = structure.select('protein', chain=chain) - residues = np.unique(selection.getResnums()) + residues = np.unique(selection.getResindices()) fo.write(f'[atomselect top all] set beta 0\n') # Single residue frustration for r, f in zip(residues, single_frustration): # print(f) - fo.write(f'[atomselect top "chain {chain} and residue {int(r)}"] set beta {f}\n') + fo.write(f'[atomselect top "residue {int(r)}"] set beta {f}\n') # Mutational frustration: r1, r2 = np.meshgrid(residues, residues, indexing='ij') @@ -965,13 +965,13 @@ def write_tcl_script(pdb_file: Union[Path,str], chain: str, mask: np.array, dist r2=int(r2) if abs(r1-r2) == 1: # don't draw interactions between residues adjacent in sequence continue - pos1 = selection.select(f'resid {r1} and chain {chain} and (name CB or (resname GLY and name CA))').getCoords()[0] - pos2 = selection.select(f'resid {r2} and chain {chain} and (name CB or (resname GLY and name CA))').getCoords()[0] + pos1 = selection.select(f'resindex {r1} and (name CB or (resname GLY and name CA))').getCoords()[0] + pos2 = selection.select(f'resindex {r2} and (name CB or (resname GLY and name CA))').getCoords()[0] distance = np.linalg.norm(pos1 - pos2) if d > 9.5 or d < 3.5: continue - fo.write(f'lassign [[atomselect top "resid {r1} and name CA and chain {chain}"] get {{x y z}}] pos1\n') - fo.write(f'lassign [[atomselect top "resid {r2} and name CA and chain {chain}"] get {{x y z}}] pos2\n') + fo.write(f'lassign [[atomselect top "residue {r1} and name CA"] get {{x y z}}] pos1\n') + fo.write(f'lassign [[atomselect top "residue {r2} and name CA"] get {{x y z}}] pos2\n') if 3.5 <= distance <= 6.5: fo.write(f'draw line $pos1 $pos2 style solid width 2\n') else: @@ -989,8 +989,8 @@ def write_tcl_script(pdb_file: Union[Path,str], chain: str, mask: np.array, dist r2=int(r2) if d > 9.5 or d < 3.5: continue - fo.write(f'lassign [[atomselect top "resid {r1} and name CA and chain {chain}"] get {{x y z}}] pos1\n') - fo.write(f'lassign [[atomselect top "resid {r2} and name CA and chain {chain}"] get {{x y z}}] pos2\n') + fo.write(f'lassign [[atomselect top "residue {r1} and name CA"] get {{x y z}}] pos1\n') + fo.write(f'lassign [[atomselect top "residue {r2} and name CA"] get {{x y z}}] pos2\n') if 3.5 <= d <= 6.5: fo.write(f'draw line $pos1 $pos2 style solid width 2\n') else: From 801b3fac69df7c231639c3b5215f198906ac502d Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Tue, 14 Apr 2026 19:12:37 -0500 Subject: [PATCH 27/28] Fixes configurational frustration call for AWSEM --- frustratometer/classes/Frustratometer.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frustratometer/classes/Frustratometer.py b/frustratometer/classes/Frustratometer.py index b441fd01..11c22c5b 100644 --- a/frustratometer/classes/Frustratometer.py +++ b/frustratometer/classes/Frustratometer.py @@ -320,15 +320,17 @@ def frustration(self, sequence:str = None, kind:str = 'singleresidue', mask:np.a sequence=self.sequence if not isinstance(mask, np.ndarray): mask=self.mask + # Configurational frustration has its own dedicated method (e.g. in AWSEM); + # dispatch before computing decoy_fluctuation which doesn't handle 'configurational'. + if kind == 'configurational' and 'configurational_frustration' in dir(self): + #TODO: Correct this function for different aa_freq than WT + return self.configurational_frustration(aa_freq, correction) decoy_fluctuation = self.decoy_fluctuation(sequence=sequence,kind=kind, mask=mask) if kind == 'singleresidue': if aa_freq is None: aa_freq = self.aa_freq frustration_values=frustration.compute_single_frustration(decoy_fluctuation, aa_freq, correction) return frustration_values - elif kind == 'configurational' and 'configurational_frustration' in dir(self): - #TODO: Correct this function for different aa_freq than WT - return self.configurational_frustration(None, correction) elif kind in ['mutational', 'pseudoconfigurational', 'contact']: if aa_freq is None: aa_freq = self.contact_freq From 9abf5a4893e4b88d79df6b19ee3da83c9efce70f Mon Sep 17 00:00:00 2001 From: Carlos Bueno Date: Sun, 19 Apr 2026 02:02:53 -0500 Subject: [PATCH 28/28] Removes array duplication --- frustratometer/classes/AWSEM.py | 46 +++++++++++++---------- frustratometer/frustration/frustration.py | 25 +++++++----- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/frustratometer/classes/AWSEM.py b/frustratometer/classes/AWSEM.py index f40d000f..96de797d 100644 --- a/frustratometer/classes/AWSEM.py +++ b/frustratometer/classes/AWSEM.py @@ -401,18 +401,20 @@ def _build_sparse(self, p, sequence_mask_contact, theta, thetaII, burial_energy, sigma_water_c = sigma_water[ci, cj] sigma_protein_c = sigma_protein[ci, cj] - # Build J_sparse in AWSEM 20-letter alphabet: (N_c, q, q) - J_sparse_20 = p.k_contact * ( - self.direct_gamma[np.newaxis, :, :] * theta_c[:, np.newaxis, np.newaxis] - + self.water_gamma[np.newaxis, :, :] * (thetaII_c * sigma_water_c)[:, np.newaxis, np.newaxis] - + self.protein_gamma[np.newaxis, :, :] * (thetaII_c * sigma_protein_c)[:, np.newaxis, np.newaxis] + dg21 = self.direct_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y] + wg21 = self.water_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y] + pg21 = self.protein_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y] + dg21[0, :] = 0; dg21[:, 0] = 0 + wg21[0, :] = 0; wg21[:, 0] = 0 + pg21[0, :] = 0; pg21[:, 0] = 0 + + # Build J_sparse directly in DCA 21-letter alphabet: (N_c, 21, 21) + J_sparse_21 = p.k_contact * ( + dg21[np.newaxis, :, :] * theta_c[:, np.newaxis, np.newaxis] + + wg21[np.newaxis, :, :] * (thetaII_c * sigma_water_c)[:, np.newaxis, np.newaxis] + + pg21[np.newaxis, :, :] * (thetaII_c * sigma_protein_c)[:, np.newaxis, np.newaxis] ) - # Map to DCA 21-letter alphabet: (N_c, 21, 21) - J_sparse_21 = J_sparse_20[:, self.aa_map_awsem_x, self.aa_map_awsem_y] - J_sparse_21[:, 0, :] = 0 - J_sparse_21[:, :, 0] = 0 - # Sparse Potts model h = burial_energy.sum(axis=-1)[:, self.aa_map_awsem_list] h[:, 0] = 0 @@ -474,18 +476,22 @@ def _build_sparse(self, p, sequence_mask_contact, theta, thetaII, burial_energy, def _build_sparse_from_contacts(self, p, ci, cj, theta_c, thetaII_c, sigma_water_c, sigma_protein_c, burial_energy, expose): """Build sparse Potts model from pre-computed contact-level values (sparse distance path).""" - # Build J_sparse in AWSEM 20-letter alphabet: (N_c, q, q) - J_sparse_20 = p.k_contact * ( - self.direct_gamma[np.newaxis, :, :] * theta_c[:, np.newaxis, np.newaxis] - + self.water_gamma[np.newaxis, :, :] * (thetaII_c * sigma_water_c)[:, np.newaxis, np.newaxis] - + self.protein_gamma[np.newaxis, :, :] * (thetaII_c * sigma_protein_c)[:, np.newaxis, np.newaxis] + # Pre-map gamma matrices to DCA 21-letter alphabet (21, 21) to avoid + # allocating the intermediate (N_c, 20, 20) tensor. + dg21 = self.direct_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y] + wg21 = self.water_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y] + pg21 = self.protein_gamma[self.aa_map_awsem_x, self.aa_map_awsem_y] + dg21[0, :] = 0; dg21[:, 0] = 0 + wg21[0, :] = 0; wg21[:, 0] = 0 + pg21[0, :] = 0; pg21[:, 0] = 0 + + # Build J_sparse directly in DCA 21-letter alphabet: (N_c, 21, 21) + J_sparse_21 = p.k_contact * ( + dg21[np.newaxis, :, :] * theta_c[:, np.newaxis, np.newaxis] + + wg21[np.newaxis, :, :] * (thetaII_c * sigma_water_c)[:, np.newaxis, np.newaxis] + + pg21[np.newaxis, :, :] * (thetaII_c * sigma_protein_c)[:, np.newaxis, np.newaxis] ) - # Map to DCA 21-letter alphabet: (N_c, 21, 21) - J_sparse_21 = J_sparse_20[:, self.aa_map_awsem_x, self.aa_map_awsem_y] - J_sparse_21[:, 0, :] = 0 - J_sparse_21[:, :, 0] = 0 - # Sparse Potts model h = burial_energy.sum(axis=-1)[:, self.aa_map_awsem_list] h[:, 0] = 0 diff --git a/frustratometer/frustration/frustration.py b/frustratometer/frustration/frustration.py index ad2f650e..28574008 100644 --- a/frustratometer/frustration/frustration.py +++ b/frustratometer/frustration/frustration.py @@ -2456,9 +2456,12 @@ def _check_seqsep(arr_i, arr_j, seq_cutoff, brks): filt_in_mask = _check_seqsep(filt_ci, filt_cj, mask_sequence_cutoff, mask_chain_breaks) else: mask_key = mask_i.astype(np.int64) * L + mask_j.astype(np.int64) - mask_set = set(mask_key.tolist()) - filt_in_mask = np.array([int(ci_v) * L + int(cj_v) in mask_set - for ci_v, cj_v in zip(filt_ci, filt_cj)]) + sort_idx_mk = np.argsort(mask_key) + sorted_mask_key = mask_key[sort_idx_mk] + filt_lookup_key = filt_ci.astype(np.int64) * L + filt_cj.astype(np.int64) + filt_pos = np.searchsorted(sorted_mask_key, filt_lookup_key) + filt_pos = np.clip(filt_pos, 0, len(sorted_mask_key) - 1) + filt_in_mask = sorted_mask_key[filt_pos] == filt_lookup_key ind_masked[~filt_in_mask] = 0.0 # phi = indicator * mask @ q_native per row i @@ -2471,16 +2474,20 @@ def _check_seqsep(arr_i, arr_j, seq_cutoff, brks): potts_cj = sparse_potts_model['contact_j'] potts_key = potts_ci.astype(np.int64) * L + potts_cj.astype(np.int64) - # Build lookup from filtered elec data - ind_lookup = {} - for k, v in zip(filt_key, ind_vals): - ind_lookup[int(k)] = v + sort_idx_filt = np.argsort(filt_key) + sorted_filt_key = filt_key[sort_idx_filt] + potts_pos = np.searchsorted(sorted_filt_key, potts_key) + potts_pos = np.clip(potts_pos, 0, len(sorted_filt_key) - 1) + found = sorted_filt_key[potts_pos] == potts_key + indicator_at_contacts = np.where(found, ind_vals[sort_idx_filt[potts_pos]], 0.0) - indicator_at_contacts = np.array([ind_lookup.get(int(k), 0.0) for k in potts_key]) if mask_sequence_cutoff is not None: mask_at_contacts = _check_seqsep(potts_ci, potts_cj, mask_sequence_cutoff, mask_chain_breaks).astype(float) else: - mask_at_contacts = np.array([1.0 if int(k) in mask_set else 0.0 for k in potts_key]) + # mask_key and sorted_mask_key already computed in the filt_in_mask branch above + mask_pos = np.searchsorted(sorted_mask_key, potts_key) + mask_pos = np.clip(mask_pos, 0, len(sorted_mask_key) - 1) + mask_at_contacts = (sorted_mask_key[mask_pos] == potts_key).astype(float) if mask_sequence_cutoff is not None: _mask_mean = mask_mean(L, mask_sequence_cutoff, mask_chain_breaks)