Coverage for ccsds124/mask.py: 100%

17 statements  

« prev     ^ index     » next       coverage.py v7.14.3, created at 2026-06-29 15:01 +0000

1""" 

2CCSDS 124.0-B-1 mask update logic. 

3 

4Implements CCSDS 124.0-B-1 Section 4 (Mask Update): 

5- Build Vector Update (Equation 6) 

6- Mask Vector Update (Equation 7) 

7- Change Vector Computation (Equation 8) 

8 

9MicroPython compatible - no typing module imports. 

10""" 

11 

12# Import for type hints only 

13if False: # noqa: SIM108 

14 from ccsds124.bitvector import BitVector 

15 

16 

17def update_build( 

18 build: "BitVector", 

19 input_vec: "BitVector", 

20 prev_input: "BitVector", 

21 new_mask_flag: bool, 

22 t: int, 

23) -> None: 

24 """ 

25 Update the build vector (CCSDS Equation 6). 

26 

27 Build vector accumulates bits that have changed over time. 

28 When new_mask_flag is set, the build is used to replace the mask 

29 and is then reset to zero. 

30 

31 Equation: 

32 - Bt = (It XOR It-1) OR Bt-1 (if t > 0 and new_mask_flag = 0) 

33 - Bt = 0 (if t = 0 or new_mask_flag = 1) 

34 

35 Args: 

36 build: Build vector to update (modified in place) 

37 input_vec: Current input vector It 

38 prev_input: Previous input vector It-1 

39 new_mask_flag: Whether a new mask is being established 

40 t: Current time step 

41 """ 

42 if t == 0 or new_mask_flag: 

43 # Reset build to zero 

44 build.zero() 

45 else: 

46 # Bt = (It XOR It-1) OR Bt-1 

47 # Create temporary for changes 

48 changes = input_vec.copy() 

49 changes.xor(changes, prev_input) 

50 

51 # Update build: build = changes OR build 

52 build.or_(build, changes) 

53 

54 

55def update_mask( 

56 mask: "BitVector", 

57 input_vec: "BitVector", 

58 prev_input: "BitVector", 

59 build_prev: "BitVector", 

60 new_mask_flag: bool, 

61) -> None: 

62 """ 

63 Update the mask vector (CCSDS Equation 7). 

64 

65 The mask tracks which bits are unpredictable. 

66 When new_mask_flag is set, the mask is replaced with the build vector. 

67 

68 Equation: 

69 - Mt = (It XOR It-1) OR Mt-1 (if new_mask_flag = 0) 

70 - Mt = (It XOR It-1) OR Bt-1 (if new_mask_flag = 1) 

71 

72 Args: 

73 mask: Mask vector to update (modified in place) 

74 input_vec: Current input vector It 

75 prev_input: Previous input vector It-1 

76 build_prev: Previous build vector Bt-1 

77 new_mask_flag: Whether a new mask is being established 

78 """ 

79 # Calculate changes: It XOR It-1 

80 changes = input_vec.copy() 

81 changes.xor(changes, prev_input) 

82 

83 if new_mask_flag: 

84 # Mt = changes OR Bt-1 

85 mask.or_(changes, build_prev) 

86 else: 

87 # Mt = changes OR Mt-1 

88 mask.or_(mask, changes) 

89 

90 

91def compute_change( 

92 change: "BitVector", 

93 mask: "BitVector", 

94 prev_mask: "BitVector", 

95 t: int, 

96) -> None: 

97 """ 

98 Compute the change vector (CCSDS Equation 8). 

99 

100 The change vector tracks which mask bits changed between time steps. 

101 This is used in encoding to communicate mask updates. 

102 

103 Equation: 

104 - Dt = Mt XOR Mt-1 (if t > 0) 

105 - Dt = 0 (if t = 0, CCSDS Eq. 8: no change at initialization) 

106 

107 Args: 

108 change: Change vector to compute (modified in place) 

109 mask: Current mask vector Mt 

110 prev_mask: Previous mask vector Mt-1 

111 t: Current time step 

112 """ 

113 if t == 0: 

114 # CCSDS Eq. 8: D0 = 0 — both encoder and decoder start from the 

115 # same user-specified M0, so there is no change to communicate 

116 change.zero() 

117 else: 

118 # Dt = Mt XOR Mt-1 

119 change.xor(mask, prev_mask)