@@ -125,18 +125,18 @@ def test_non_dsn_priority_blocking_with_kernels(furnish_kernels):
125125 "imap_processing.ialirt.generate_coverage.NON_DSN_STATIONS" ,
126126 new = {"Kiel" : STATIONS ["Kiel" ]},
127127 ):
128- cov_kiel , _ = generate_coverage (start_time )
128+ coverage_kiel , _ = generate_coverage (start_time )
129129
130- kiel_times = cov_kiel ["Kiel" ]
130+ kiel_times = coverage_kiel ["Kiel" ]
131131
132132 # Manaus-only coverage
133133 with patch (
134134 "imap_processing.ialirt.generate_coverage.NON_DSN_STATIONS" ,
135135 new = {"Manaus" : STATIONS ["Manaus" ]},
136136 ):
137- cov_manaus_only , _ = generate_coverage (start_time )
137+ coverage_manaus_only , _ = generate_coverage (start_time )
138138
139- manaus_only_times = cov_manaus_only ["Manaus" ]
139+ manaus_only_times = coverage_manaus_only ["Manaus" ]
140140
141141 overlap = np .intersect1d (kiel_times , manaus_only_times )
142142 # Assert the times overlap.
@@ -158,3 +158,59 @@ def test_non_dsn_priority_blocking_with_kernels(furnish_kernels):
158158 blocked_overlap = np .intersect1d (kiel_times , manaus_coverage )
159159 assert blocked_overlap .size == 0
160160 assert manaus_coverage [0 ] > kiel_times [- 1 ]
161+
162+
163+ @pytest .mark .external_kernel
164+ def test_dsn_outage_allows_ground_station_coverage (furnish_kernels ):
165+ """
166+ DSN contacts block non-DSN stations, but DSN outages remove blocking.
167+ """
168+ kernels = ["naif0012.tls" , "pck00011.tpc" , "de440s.bsp" , "imap_spk_demo.bsp" ]
169+ start_time = "2026-09-22T00:00:00Z"
170+
171+ with furnish_kernels (kernels ):
172+ # Baseline Kiel-only coverage (no DSN)
173+ with patch (
174+ "imap_processing.ialirt.generate_coverage.NON_DSN_STATIONS" ,
175+ new = {"Kiel" : STATIONS ["Kiel" ]},
176+ ):
177+ coverage_base , _ = generate_coverage (start_time )
178+
179+ kiel_times = coverage_base ["Kiel" ]
180+
181+ contact_start = kiel_times [10 ] # inside Kiel coverage
182+ contact_end = kiel_times [16 ] # 30 min later (inclusive logic in your code)
183+
184+ # Outage inside the DSN contact
185+ outage_start = kiel_times [12 ]
186+ outage_end = kiel_times [14 ]
187+
188+ dsn = {"DSS-75" : [(contact_start , contact_end )]}
189+
190+ # DSN contact, no DSN outage
191+ # Kiel should be blocked during the full contact window
192+ with patch (
193+ "imap_processing.ialirt.generate_coverage.NON_DSN_STATIONS" ,
194+ new = {"Kiel" : STATIONS ["Kiel" ]},
195+ ):
196+ coverage_blocked , _ = generate_coverage (start_time , dsn = dsn , outages = None )
197+
198+ kiel_blocked = coverage_blocked ["Kiel" ]
199+
200+ assert not np .any (np .isin (kiel_times [10 :16 ], kiel_blocked ))
201+
202+ # DSN contact + DSN outage
203+ # Kiel allowed during outage sub-window
204+ outages = {"DSS-75" : [(outage_start , outage_end )]}
205+
206+ with patch (
207+ "imap_processing.ialirt.generate_coverage.NON_DSN_STATIONS" ,
208+ new = {"Kiel" : STATIONS ["Kiel" ]},
209+ ):
210+ coverage_punched , _ = generate_coverage (
211+ start_time , dsn = dsn , outages = outages
212+ )
213+
214+ kiel_punched = coverage_punched ["Kiel" ]
215+
216+ assert np .all (np .isin (kiel_times [12 :14 ], kiel_punched ))
0 commit comments