@@ -226,6 +226,11 @@ def test_rubin_diffraction_produces_spikes() -> None:
226226
227227 # Define a tolerance for the spike width in rad:
228228 spike_angle_tolerance = np .pi / 6.0
229+ # Determine the total fraction of a circle taken up by all regions of this
230+ # size, and regions outside of the spikes:
231+ spike_fraction = 2. * spike_angle_tolerance / np .pi
232+ non_spike_fraction = 1. - spike_fraction
233+ weight = spike_fraction / non_spike_fraction
229234
230235 delta_angles = spike_angles - cross_rot_angle
231236 delta_angles [delta_angles < 0.0 ] += 2.0 * np .pi
@@ -248,11 +253,29 @@ def test_rubin_diffraction_produces_spikes() -> None:
248253 # Merge last and first bin:
249254 h [0 ] += h [- 1 ]
250255 h = h [:- 1 ]
256+ # Weight the non-spike counts in h to account for the different bin sizes.
257+ h [1 ::2 ] = h [1 ::2 ] * weight
251258
252- # Check that there less than 0.5% of the spike photons outside of the spike regions:
253- np .testing .assert_array_less (h [1 ::2 ], spike_angles .size // 200 )
254- # Check that there are photons in all spike regions:
255- np .testing .assert_array_less (0 , h [0 ::2 ])
259+ # The min and max counts we might expect in a bin of size
260+ # spike_angle_tolerance if there were only non-spike photons, with some
261+ # amount of Poisson noise.
262+ bg_level_min = np .mean (h [1 ::2 ]) - 2. * np .sqrt (np .mean (h [1 ::2 ]))
263+ bg_level_max = np .mean (h [1 ::2 ]) + 2. * np .sqrt (np .mean (h [1 ::2 ]))
264+
265+ # Assert all out-of-spike regions are within that range.
266+ np .testing .assert_array_less (bg_level_min , h [1 ::2 ])
267+ np .testing .assert_array_less (h [1 ::2 ], bg_level_max )
268+
269+ # Perform the same checks on spike regions.
270+ spike_level_min = np .mean (h [0 ::2 ]) - 2. * np .sqrt (np .mean (h [0 ::2 ]))
271+ spike_level_max = np .mean (h [0 ::2 ]) + 2. * np .sqrt (np .mean (h [0 ::2 ]))
272+ np .testing .assert_array_less (spike_level_min , h [0 ::2 ])
273+ np .testing .assert_array_less (h [0 ::2 ], spike_level_max )
274+
275+ # Check that each of the spike bins are measured above the non-spike
276+ # level + an appreciable noise level.
277+ high_bg = np .mean (h [1 ::2 ]) + 10. * np .sqrt (np .mean (h [1 ::2 ]))
278+ np .testing .assert_array_less (high_bg , h [0 ::2 ])
256279
257280
258281def test_rubin_diffraction_optics_is_same_as_diffraction_and_optics () -> None :
@@ -357,8 +380,8 @@ def test_rubin_diffraction_shows_field_rotation() -> None:
357380 )
358381
359382 # Find the angle, the cross is rotated relative to the axis cross:
360- cross_rot_angle_0 = np .mean (spike_angles_0 % (np .pi / 2.0 ))
361- cross_rot_angle_1 = np .mean (spike_angles_1 % (np .pi / 2.0 ))
383+ cross_rot_angle_0 = np .median (spike_angles_0 % (np .pi / 2.0 ))
384+ cross_rot_angle_1 = np .median (spike_angles_1 % (np .pi / 2.0 ))
362385
363386 # Check that the angle of the crosses are rotated relative to each other:
364387 expected_angle_difference = field_rotation_angle (latitude , altitude , azimuth , dt )
0 commit comments