Skip to content
2 changes: 2 additions & 0 deletions openms_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from .py_consensusmap import Py_ConsensusMap
from .py_experimentaldesign import Py_ExperimentalDesign
from .py_aasequence import Py_AASequence
from .py_residue import Py_Residue
from .py_identifications import (
ProteinIdentifications,
PeptideIdentifications,
Expand Down Expand Up @@ -109,6 +110,7 @@ def get_example(name: str, *, load: bool = False, target_dir: Union[str, Path, N
"Py_ConsensusMap",
"Py_ExperimentalDesign",
"Py_AASequence",
"Py_Residue",
"ProteinIdentifications",
"PeptideIdentifications",
"Identifications",
Expand Down
18 changes: 12 additions & 6 deletions openms_python/py_aasequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Optional, Literal
import pyopenms as oms
import warnings
from .py_residue import Py_Residue


class Py_AASequence:
Expand Down Expand Up @@ -64,10 +65,10 @@ def from_native(cls, native_sequence: oms.AASequence) -> Py_AASequence:
Creates Py_AASequence from native pyOpenMS AASequence.

Args:
native_sequence (oms.AASequence):
native_sequence (oms.AASequence): Native pyOpenMS AASequence object.

Returns:
Py_AASequence: New wrapped opject
Py_AASequence: New wrapped object.

"""
return cls(native_sequence)
Expand Down Expand Up @@ -242,20 +243,20 @@ def __getitem__(self, index):
if step != 1:
raise ValueError("Step slicing is not supported for amino acid sequences")
return Py_AASequence.from_native(self._sequence.getSubsequence(start, stop - start))
else:
else: # isinstance(index, int)
# Handle negative indices
if index < 0:
index = len(self) + index
if index >= len(self):
raise IndexError(f"Index {index} out of range for sequence of length {len(self)}")
residue = self._sequence.getSubsequence(index, 1)
return Py_AASequence.from_native(residue)
residue = self._sequence.getResidue(index)
return Py_Residue.from_native(residue)

def __iter__(self):
"""Iterate over residues."""
for i in range(len(self)):
yield self[i]
def __add__(self, other: Py_AASequence | str) -> Py_AASequence:
def __add__(self, other: Py_AASequence | str | Py_Residue) -> Py_AASequence:
"""
Concatenate sequences.

Expand All @@ -279,6 +280,8 @@ def __add__(self, other: Py_AASequence | str) -> Py_AASequence:
combined_str = self.sequence + other.sequence
elif isinstance(other, str):
combined_str = self.sequence + other
elif isinstance(other, Py_Residue):
combined_str = self.sequence + other.one_letter_code
else:
return NotImplemented
return Py_AASequence.from_string(combined_str)
Expand All @@ -296,6 +299,9 @@ def __radd__(self, other: str) -> Py_AASequence:
if isinstance(other, str):
combined_str = other + self.sequence
return Py_AASequence.from_string(combined_str)
if isinstance(other, Py_Residue):
combined_str = other.one_letter_code + self.sequence
return Py_AASequence.from_string(combined_str)
return NotImplemented

def __mul__(self, times: int) -> Py_AASequence:
Expand Down
Loading
Loading