Coverage for tests/test_dense.py: 100%

125 statements  

« prev     ^ index     » next       coverage.py v7.15.1, created at 2026-07-18 05:24 +0000

1import numpy as np 

2import pytest 

3 

4from evutils.types import Event_dtype, EventArray 

5from evutils.dense import ( 

6 timesurface, 

7 voxel_histogram, 

8 histogram, 

9 wedge_histogram, 

10 frame_diff, 

11 frame_rgb, 

12 frame_gray, 

13 tore 

14) 

15 

16@pytest.fixture(params=["aos", "soa"]) 

17def event_format(request): 

18 return request.param 

19 

20def create_events(data, format="aos"): 

21 events = np.zeros(len(data), dtype=Event_dtype) 

22 for i, (t, x, y, p) in enumerate(data): 

23 events[i]['t'] = t 

24 events[i]['x'] = x 

25 events[i]['y'] = y 

26 events[i]['p'] = p 

27 

28 if format == "soa": 

29 return EventArray.from_aos(events) 

30 return events 

31 

32def test_timesurface(event_format): 

33 events = create_events([(100, 10, 20, 1), (200, 15, 25, 0)], format=event_format) 

34 ts = timesurface(events, width=100, height=50, tau=100) 

35 assert ts.shape == (50, 100) 

36 assert ts[20, 10] == pytest.approx(np.exp(-(200 - 100) / 100.0)) 

37 assert ts[25, 15] == pytest.approx(-1.0) 

38 

39def test_timesurface_empty(event_format): 

40 events = create_events([], format=event_format) 

41 ts = timesurface(events, width=100, height=50) 

42 assert ts.shape == (50, 100) 

43 assert np.all(ts == 0) 

44 

45def test_voxel_histogram(event_format): 

46 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0), (200, 10, 20, 1)], format=event_format) 

47 vh = voxel_histogram(events, width=100, height=50, n_bins=2, dt=100) 

48 assert vh.shape == (2, 50, 100, 3) 

49 

50def test_voxel_histogram_empty(event_format): 

51 events = create_events([], format=event_format) 

52 vh = voxel_histogram(events, width=100, height=50, n_bins=10, dt=1000) 

53 assert vh.shape == (10, 50, 100, 3) 

54 assert np.all(vh == 0) 

55 

56def test_voxel_histogram_less_than_3_events(event_format): 

57 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0)], format=event_format) 

58 vh = voxel_histogram(events, width=100, height=50, n_bins=2, dt=100) 

59 assert vh.shape == (2, 50, 100, 3) 

60 assert np.all(vh == 0) 

61 

62def test_voxel_histogram_exceeds_dt(event_format): 

63 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0), (250, 10, 20, 1)], format=event_format) 

64 with pytest.raises(ValueError): 

65 voxel_histogram(events, width=100, height=50, n_bins=2, dt=100) 

66 

67def test_histogram(event_format): 

68 events = create_events([(100, 10, 20, 1), (200, 15, 25, 0), (250, 10, 20, 1)], format=event_format) 

69 h = histogram(events, width=100, height=50, fill=False) 

70 assert h.shape == (50, 100, 3) 

71 assert h[20, 10, 0] == 2 # Red channel for p=1 

72 assert h[25, 15, 2] == 1 # Blue channel for p=0 

73 

74def test_histogram_empty(event_format): 

75 events = create_events([], format=event_format) 

76 h = histogram(events, width=100, height=50) 

77 assert h.shape == (50, 100, 3) 

78 assert np.all(h == 0) 

79 

80def test_histogram_fill(event_format): 

81 events = create_events([(100, 10, 20, 1)], format=event_format) 

82 h = histogram(events, width=100, height=50, fill=True) 

83 assert h.shape == (50, 100, 3) 

84 assert h[20, 10, 0] == 255 

85 

86def test_wedge_histogram(event_format): 

87 events = create_events([(100, 10, 20, 1), (200, 15, 25, 0)], format=event_format) 

88 wh = wedge_histogram(events, width=100, height=50, tl=300) 

89 assert wh.shape == (50, 100, 3) 

90 

91def test_frame_diff(event_format): 

92 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0), (200, 10, 20, 1)], format=event_format) 

93 fd = frame_diff(events, width=100, height=50) 

94 assert fd.shape == (50, 100) 

95 assert fd[20, 10] == 2 

96 assert fd[25, 15] == -1 

97 

98def test_frame_diff_empty(event_format): 

99 events = create_events([], format=event_format) 

100 fd = frame_diff(events, width=100, height=50) 

101 assert fd.shape == (50, 100) 

102 assert np.all(fd == 0) 

103 

104def test_frame_rgb(event_format): 

105 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0)], format=event_format) 

106 frgb = frame_rgb(events, width=100, height=50) 

107 assert frgb.shape == (50, 100, 3) 

108 assert np.array_equal(frgb[20, 10], [255, 0, 0]) 

109 assert np.array_equal(frgb[25, 15], [0, 0, 255]) 

110 assert np.array_equal(frgb[0, 0], [0, 0, 0]) 

111 

112def test_frame_gray(event_format): 

113 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0)], format=event_format) 

114 fg = frame_gray(events, width=100, height=50) 

115 assert fg.shape == (50, 100) 

116 assert fg[20, 10] == 255 

117 assert fg[25, 15] == 0 

118 assert fg[0, 0] == 128 

119 

120def test_tore(event_format): 

121 events = create_events([(100, 10, 20, 1), (150, 15, 25, 0), (200, 10, 20, 1)], format=event_format) 

122 t = tore(events, width=100, height=50, n_events=2, tau=100) 

123 assert t.shape == (50, 100, 2, 2) 

124 assert t[20, 10, 1, 1] == pytest.approx(1.0) 

125 assert t[20, 10, 0, 1] == pytest.approx(np.exp(-1.0)) 

126 

127def test_tore_empty(event_format): 

128 events = create_events([], format=event_format) 

129 t = tore(events, width=100, height=50, n_events=4) 

130 assert t.shape == (50, 100, 4, 2) 

131 assert np.all(t == 0) 

132 

133# --- saturation / overflow edge cases (branch coverage) -------------------- 

134 

135def test_histogram_saturation(event_format): 

136 events = create_events([(i, 10, 20, 1) for i in range(300)], format=event_format) 

137 h = histogram(events, width=100, height=50, fill=False) 

138 assert h[20, 10, 0] == 255 

139 

140def test_wedge_histogram_saturation(event_format): 

141 events = create_events([(100, 10, 20, 1), (200, 10, 20, 1)], format=event_format) 

142 wh = wedge_histogram(events, width=100, height=50, tl=300) 

143 assert wh[20, 10, 0] == 255 

144 

145def test_tore_fifo_overflow(event_format): 

146 events = create_events([(100, 10, 20, 1), (150, 10, 20, 1), (200, 10, 20, 1)], format=event_format) 

147 t = tore(events, width=100, height=50, n_events=2, tau=100) 

148 assert t.shape == (50, 100, 2, 2) 

149 assert t[20, 10, 1, 1] == pytest.approx(1.0) 

150 assert t[20, 10, 0, 1] == pytest.approx(np.exp(-0.5)) 

151 

152def test_voxel_histogram_more_windows_than_bins(event_format): 

153 events = create_events([(0, 10, 20, 1), (50, 11, 21, 0), (100, 12, 22, 1)], format=event_format) 

154 vh = voxel_histogram(events, width=100, height=50, n_bins=2, dt=100) 

155 assert vh.shape == (2, 50, 100, 3) 

156 

157def test_voxel_histogram_fewer_windows_than_bins(event_format): 

158 events = create_events([(0, 10, 20, 1), (10, 11, 21, 0), (20, 12, 22, 1)], format=event_format) 

159 vh = voxel_histogram(events, width=100, height=50, n_bins=10, dt=10000) 

160 assert vh.shape == (10, 50, 100, 3) 

161 assert np.all(vh[1:] == 0)