Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from typing import Optional 

2from warnings import warn 

3 

4from Bio import AlignIO 

5from Bio.Align import MultipleSeqAlignment 

6 

7from ..utils import PhytestObject, assert_or_warn 

8 

9 

10class Alignment(PhytestObject, MultipleSeqAlignment): 

11 @classmethod 

12 def read(cls, alignment_path, alignment_format) -> 'Alignment': 

13 alignment = AlignIO.read(alignment_path, alignment_format) 

14 return Alignment( 

15 alignment._records, annotations=alignment.annotations, column_annotations=alignment.column_annotations 

16 ) 

17 

18 def assert_width( 

19 self, 

20 width: Optional[int] = None, 

21 *, 

22 min: Optional[int] = None, 

23 max: Optional[int] = None, 

24 warning: bool = False, 

25 ) -> None: 

26 """ 

27 Asserts that the alignment width (the number of bases in the sequences) meets the specified criteria. 

28 

29 Args: 

30 length (int, optional): If set, then alignment width must be equal to this value. Defaults to None. 

31 min (int, optional): If set, then alignment width must be equal to or greater than this value. Defaults to None. 

32 max (int, optional): If set, then alignment width must be equal to or less than this value. Defaults to None. 

33 warning (bool): If True, raise a warning instead of an exception. Defaults to False. 

34 This flag can be set by running this method with the prefix `warn_` instead of `assert_`. 

35 """ 

36 alignment_width = self.get_alignment_length() 

37 summary = f"The width of the alignment is {alignment_width}." 

38 

39 if width is not None: 

40 assert_or_warn( 

41 alignment_width == width, 

42 warning, 

43 summary, 

44 f"This is not equal to the required width of {width}.", 

45 ) 

46 if min is not None: 

47 assert_or_warn( 

48 alignment_width >= min, 

49 warning, 

50 summary, 

51 f"This is less than the minimum width of {min}.", 

52 ) 

53 if max is not None: 

54 assert_or_warn( 

55 alignment_width <= max, 

56 warning, 

57 summary, 

58 f"This is greater than the maximum width of {max}.", 

59 ) 

60 

61 def assert_length( 

62 self, 

63 length: Optional[int] = None, 

64 *, 

65 min: Optional[int] = None, 

66 max: Optional[int] = None, 

67 warning: bool = False, 

68 ) -> None: 

69 """ 

70 Asserts that the alignment length (the number of sequences in the alignment) meets the specified criteria. 

71 

72 Args: 

73 length (int, optional): If set, then alignment length must be equal to this value. Defaults to None. 

74 min (int, optional): If set, then alignment length must be equal to or greater than this value. Defaults to None. 

75 max (int, optional): If set, then alignment length must be equal to or less than this value. Defaults to None. 

76 warning (bool): If True, raise a warning instead of an exception. Defaults to False. 

77 This flag can be set by running this method with the prefix `warn_` instead of `assert_`. 

78 """ 

79 alignment_length = len(self) 

80 summary = f"The number of sequences in the alignment is {alignment_length}." 

81 

82 if length is not None: 

83 assert_or_warn( 

84 alignment_length == length, 

85 warning, 

86 summary, 

87 f"This is less than required number of {length}.", 

88 ) 

89 if min is not None: 

90 assert_or_warn( 

91 alignment_length >= min, 

92 warning, 

93 summary, 

94 f"This is less than the minimum {min}.", 

95 ) 

96 if max is not None: 

97 assert_or_warn( 

98 alignment_length <= max, 

99 warning, 

100 summary, 

101 f"This is greater than the maximum {max}.", 

102 )