This repository was archived by the owner on Jul 14, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_detection_multi.py
More file actions
258 lines (223 loc) · 7.87 KB
/
Copy pathtest_detection_multi.py
File metadata and controls
258 lines (223 loc) · 7.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#!/usr/bin/env python3
"""
Unit tests for multi-detection data structures
"""
import json
import tempfile
import os
import pytest
from detection_multi import DetectionSet, SolverConfig, quick_validation, load_detections_multi
from detection_triple import Detection, InitialGuess
def test_solver_config():
"""Test SolverConfig creation and defaults"""
# Default config
config = SolverConfig()
assert config.outlier_threshold == 3.0
assert config.min_detections == 3
assert config.max_detections == 20
assert config.max_iterations == 2
# Config from dict
config_dict = {
'outlier_threshold': 2.5,
'min_detections': 4,
'max_detections': 15
}
config = SolverConfig.from_dict(config_dict)
assert config.outlier_threshold == 2.5
assert config.min_detections == 4
assert config.max_detections == 15
assert config.max_iterations == 2 # Default
def test_detection_set_creation():
"""Test DetectionSet creation with multiple detections"""
# Create test detections
det1 = Detection(-51.0, 17.0, -50.9, 17.1, 100.0, 1234567890, 70.0, 10.0)
det2 = Detection(-51.1, 17.1, -50.9, 17.1, 100.0, 1234567890, 72.0, 15.0)
det3 = Detection(-51.2, 17.2, -50.9, 17.1, 100.0, 1234567890, 74.0, 20.0)
detection_set = DetectionSet([det1, det2, det3])
assert len(detection_set.detections) == 3
assert detection_set.initial_guess is None
assert detection_set.solver_config is not None
assert detection_set.solver_config.min_detections == 3
def test_detection_set_from_json():
"""Test parsing DetectionSet from JSON"""
test_data = {
"detection1": {
"sensor_lat": -51.0,
"sensor_lon": 17.0,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 70.0,
"doppler_hz": 10.0
},
"detection2": {
"sensor_lat": -51.1,
"sensor_lon": 17.1,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 72.0,
"doppler_hz": 15.0
},
"detection3": {
"sensor_lat": -51.2,
"sensor_lon": 17.2,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 74.0,
"doppler_hz": 20.0
},
"solver_config": {
"outlier_threshold": 2.5
}
}
json_string = json.dumps(test_data)
detection_set = DetectionSet.from_json(json_string)
assert len(detection_set.detections) == 3
assert detection_set.solver_config.outlier_threshold == 2.5
# Test ENU origin calculation
origin = detection_set.get_enu_origin()
expected_lat = (-51.0 + -51.1 + -51.2) / 3
expected_lon = (17.0 + 17.1 + 17.2) / 3
assert abs(origin[0] - expected_lat) < 1e-10
assert abs(origin[1] - expected_lon) < 1e-10
assert origin[2] == 0
def test_detection_set_with_initial_guess():
"""Test DetectionSet with initial guess"""
test_data = {
"detection1": {
"sensor_lat": -51.0,
"sensor_lon": 17.0,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 70.0,
"doppler_hz": 10.0
},
"detection2": {
"sensor_lat": -51.1,
"sensor_lon": 17.1,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 72.0,
"doppler_hz": 15.0
},
"detection3": {
"sensor_lat": -51.2,
"sensor_lon": 17.2,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 74.0,
"doppler_hz": 20.0
},
"initial_guess": {
"position_lla": {
"lat": -51.1,
"lon": 17.1,
"alt": 10000.0
},
"velocity_enu": {
"east": 100.0,
"north": 200.0,
"up": 50.0
}
}
}
json_string = json.dumps(test_data)
detection_set = DetectionSet.from_json(json_string)
assert detection_set.initial_guess is not None
assert detection_set.initial_guess.position_lla == (-51.1, 17.1, 10000.0)
assert detection_set.initial_guess.velocity_enu == (100.0, 200.0, 50.0)
# Test ENU conversion
enu_guess = detection_set.get_initial_guess_enu()
assert enu_guess is not None
assert len(enu_guess) == 6
# Velocity should be unchanged
assert enu_guess[3] == 100.0
assert enu_guess[4] == 200.0
assert enu_guess[5] == 50.0
def test_quick_validation():
"""Test quick validation function"""
# Valid detection
good_det = Detection(-51.0, 17.0, -50.9, 17.1, 100.0, 1234567890, 70.0, 10.0)
assert quick_validation(good_det) == True
# Invalid range (too small)
bad_range = Detection(-51.0, 17.0, -50.9, 17.1, 100.0, 1234567890, 5.0, 10.0)
assert quick_validation(bad_range) == False
# Invalid range (too large)
bad_range2 = Detection(-51.0, 17.0, -50.9, 17.1, 100.0, 1234567890, 1500.0, 10.0)
assert quick_validation(bad_range2) == False
# Invalid Doppler (too large)
bad_doppler = Detection(-51.0, 17.0, -50.9, 17.1, 100.0, 1234567890, 70.0, 15000.0)
assert quick_validation(bad_doppler) == False
def test_validation_errors():
"""Test validation error handling"""
# Too few detections
det1 = Detection(-51.0, 17.0, -50.9, 17.1, 100.0, 1234567890, 70.0, 10.0)
det2 = Detection(-51.1, 17.1, -50.9, 17.1, 100.0, 1234567890, 72.0, 15.0)
detection_set = DetectionSet([det1, det2]) # Only 2 detections
with pytest.raises(ValueError, match="Insufficient detections"):
detection_set.validate_all()
# Too many detections
detections = []
for i in range(25): # More than max_detections (20)
det = Detection(-51.0 + i*0.01, 17.0, -50.9, 17.1, 100.0, 1234567890, 70.0, 10.0)
detections.append(det)
detection_set = DetectionSet(detections)
with pytest.raises(ValueError, match="Too many detections"):
detection_set.validate_all()
def test_load_detections_multi():
"""Test loading from file"""
test_data = {
"detection1": {
"sensor_lat": -51.0,
"sensor_lon": 17.0,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 70.0,
"doppler_hz": 10.0
},
"detection2": {
"sensor_lat": -51.1,
"sensor_lon": 17.1,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 72.0,
"doppler_hz": 15.0
},
"detection3": {
"sensor_lat": -51.2,
"sensor_lon": 17.2,
"ioo_lat": -50.9,
"ioo_lon": 17.1,
"freq_mhz": 100.0,
"timestamp": 1234567890,
"bistatic_range_km": 74.0,
"doppler_hz": 20.0
}
}
# Create temporary file
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
json.dump(test_data, f)
temp_file = f.name
try:
detection_set = load_detections_multi(temp_file)
assert len(detection_set.detections) == 3
assert detection_set.solver_config.min_detections == 3
finally:
os.unlink(temp_file)
if __name__ == "__main__":
pytest.main([__file__, "-v"])