def test_save_load(tmp_path): path = str(tmp_path / 'test.pkl') mapping = SSTCameraMapping(n_pixels=23) camera = Camera(mapping=mapping) camera.save(path) camera_loaded = Camera.load(path) assert camera_loaded.mapping.n_pixels == 23
def test_get_sampled_waveform(): camera = Camera() acquisition = EventAcquisition(camera=camera) n_pixels = camera.mapping.n_pixels time_axis = camera.continuous_readout_time_axis n_continuous_samples = time_axis.size n_samples = camera.n_waveform_samples sample = camera.get_waveform_sample_from_time csample = camera.get_continuous_readout_sample_from_time cwidth = camera.continuous_readout_sample_width continuous_readout = np.zeros((n_pixels, n_continuous_samples)) continuous_readout[0, csample(30.0):csample(30.5)] = 100 continuous_readout[2, csample(40.0):csample(41.0)] = 100 waveform = acquisition.get_sampled_waveform(continuous_readout) assert waveform.shape == (n_pixels, n_samples) assert waveform[0].sum() == continuous_readout[0].sum() * cwidth assert waveform[2].sum() == continuous_readout[2].sum() * cwidth assert waveform[0].argmax() == sample(30.0) assert waveform[2].argmax() == sample(40.0) waveform = acquisition.get_sampled_waveform(continuous_readout, 30) assert waveform.shape == (n_pixels, n_samples) assert waveform[0].sum() == continuous_readout[0].sum() * cwidth assert waveform[2].sum() == continuous_readout[2].sum() * cwidth assert waveform[0].argmax() == sample(20.0) assert waveform[2].argmax() == sample(30.0) waveform = acquisition.get_sampled_waveform(continuous_readout, 25) assert waveform.shape == (n_pixels, n_samples) assert waveform[0].sum() == continuous_readout[0].sum() * cwidth assert waveform[2].sum() == continuous_readout[2].sum() * cwidth assert waveform[0].argmax() == sample(25.0) assert waveform[2].argmax() == sample(35.0) # Out of bounds with pytest.raises(ValueError): acquisition.get_sampled_waveform(continuous_readout, 10) with pytest.raises(ValueError): acquisition.get_sampled_waveform(continuous_readout, 900) # Single Pixel camera = Camera(mapping=SSTCameraMapping(n_pixels=1)) acquisition = EventAcquisition(camera=camera) n_pixels = camera.mapping.n_pixels time_axis = camera.continuous_readout_time_axis n_continuous_samples = time_axis.size n_samples = camera.waveform_duration * camera.waveform_sample_width continuous_readout = np.zeros((n_pixels, n_continuous_samples)) continuous_readout[0, csample(30.0):csample(30.5)] = 100 waveform = acquisition.get_sampled_waveform(continuous_readout) assert waveform.shape == (n_pixels, n_samples) assert waveform[0].sum() == continuous_readout[0].sum() * cwidth assert waveform[0].argmax() == sample(30.0) waveform = acquisition.get_sampled_waveform(continuous_readout, 30) assert waveform.shape == (n_pixels, n_samples) assert waveform[0].sum() == continuous_readout[0].sum() * cwidth assert waveform[0].argmax() == sample(20.0)
def test_n_pixels(): camera = Camera() assert camera.mapping.n_pixels == 2048 assert camera.mapping.n_superpixels == 512 camera = Camera(mapping=SSTCameraMapping(n_pixels=2)) assert camera.mapping.n_pixels == 2 assert camera.mapping.n_superpixels == 1
def test_camera(): # Default Initialisation Camera() # Custom Initialisation pulse = GaussianPulse() spectrum = SiPMGentileSPE() camera = Camera(photoelectron_pulse=pulse, photoelectron_spectrum=spectrum) assert camera.mapping.n_pixels == 2048 assert camera.photoelectron_pulse == pulse assert camera.photoelectron_spectrum == spectrum
def test_reference_pulses(trigger_class): camera = Camera() n_pixels = camera.mapping.n_pixels n_samples = camera.continuous_readout_time_axis.size trigger = trigger_class(camera) continuous_readout = np.zeros((n_pixels, n_samples)) time = 10 sample = camera.get_continuous_readout_sample_from_time(time) continuous_readout[:, sample] = 10000 trigger_times = trigger(continuous_readout) assert np.unique(trigger_times).size == 1 assert trigger_times[0] == time
def test_get_backplane_trigger(): camera = Camera() trigger = NNSuperpixelAboveThreshold(camera=camera) n_superpixels = camera.mapping.n_superpixels n_samples = camera.continuous_readout_time_axis.size csample = camera.get_continuous_readout_sample_from_time trigger_readout = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_time, trigger_pair = trigger.get_backplane_trigger( trigger_readout, return_pairs=True ) assert trigger_time.shape == (0,) assert trigger_pair.shape == (0, 2) # No overlap (after sampling) trigger_readout = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_readout[0, csample(1.00):csample(2.00)] = True trigger_readout[0, csample(10.0):csample(12.0)] = True trigger_readout[1, csample(11.5):csample(13.0)] = True trigger_readout[2, csample(20.0):csample(22.0)] = True trigger_readout[3, csample(21.5):csample(23.0)] = True trigger_time, trigger_pair = trigger.get_backplane_trigger( trigger_readout, return_pairs=True ) assert trigger_time.shape == (0,) assert trigger_pair.shape == (0, 2) trigger_readout = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_readout[0, csample(1.00):csample(2.00)] = True trigger_readout[0, csample(10.0):csample(12.5)] = True trigger_readout[1, csample(11.5):csample(13.0)] = True trigger_readout[2, csample(20.0):csample(22.5)] = True trigger_readout[3, csample(21.5):csample(23.0)] = True trigger_time, trigger_pair = trigger.get_backplane_trigger( trigger_readout, return_pairs=True ) assert trigger_time.shape == (2,) assert trigger_pair.shape == (2, 2) assert np.array_equal(trigger_time, np.array([12, 22])) assert np.array_equal(trigger_pair, np.array([[0, 1], [2, 3]])) # Single pixel camera = Camera(mapping=SSTCameraMapping(n_pixels=1)) trigger = NNSuperpixelAboveThreshold(camera=camera) n_superpixels = camera.mapping.n_superpixels n_samples = camera.continuous_readout_time_axis.size trigger_readout = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_readout[0, 10:20] = True trigger_readout[0, 100:125] = True trigger_time, trigger_pair = trigger.get_backplane_trigger( trigger_readout, return_pairs=True ) assert trigger_time.shape == (0,) assert trigger_pair.shape == (0, 2)
def test_get_digital_trigger_readout(): camera = Camera(mapping=SSTCameraMapping(n_pixels=2)) trigger = NNSuperpixelAboveThreshold(camera=camera) n_pixels = trigger.camera.mapping.n_pixels n_superpixels = trigger.camera.mapping.n_superpixels time_axis = trigger.camera.continuous_readout_time_axis n_samples = time_axis.size division = trigger.camera.continuous_readout_sample_division length = trigger.camera.digital_trigger_length * division continuous_readout = np.zeros((n_pixels, n_samples)) continuous_readout[0, 100:101] = 100 continuous_readout[0, 200:500] = 0.1 continuous_readout[1, 200:500] = 100 continuous_readout[1, 510:520] = 100 trigger_readout_expected = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_readout_expected[0, 100] = True trigger_readout_expected[0, 200] = True trigger_readout_expected[0, 510] = True trigger_readout = trigger.get_superpixel_digital_trigger_line(continuous_readout) assert np.array_equal(trigger_readout, trigger_readout_expected) # Add window trigger_readout_expected = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_readout_expected[0, 100:101+length] = True trigger_readout_expected[0, 200:201+length] = True trigger_readout_expected[0, 510:511+length] = True trigger_readout = trigger.extend_by_digital_trigger_length(trigger_readout) assert np.array_equal(trigger_readout, trigger_readout_expected)
def test_seed(): camera = Camera() simulator_1 = PhotoelectronSource(camera) simulator_2 = PhotoelectronSource(camera) simulator_3 = PhotoelectronSource(camera, seed=simulator_2.seed) simulator_4 = PhotoelectronSource(camera, seed=1) simulator_5 = PhotoelectronSource(camera, seed=1) simulator_6 = PhotoelectronSource(camera, seed=2) # get_nsb sim_1 = simulator_1.get_nsb(rate=1000) sim_2 = simulator_2.get_nsb(rate=1000) sim_3 = simulator_3.get_nsb(rate=1000) sim_4 = simulator_4.get_nsb(rate=1000) sim_5 = simulator_5.get_nsb(rate=1000) sim_6 = simulator_6.get_nsb(rate=1000) assert sim_1 != sim_2 assert sim_2 != sim_3 # Generator has been progressed assert sim_3 != sim_4 assert sim_4 == sim_5 assert sim_5 != sim_6 # get_uniform_illumination kwargs = dict(time=40, illumination=50, laser_pulse_width=2) sim_1 = simulator_1.get_uniform_illumination(**kwargs) sim_2 = simulator_2.get_uniform_illumination(**kwargs) sim_3 = simulator_3.get_uniform_illumination(**kwargs) sim_4 = simulator_4.get_uniform_illumination(**kwargs) sim_5 = simulator_5.get_uniform_illumination(**kwargs) sim_6 = simulator_6.get_uniform_illumination(**kwargs) assert sim_1 != sim_2 assert sim_2 != sim_3 # Generator has been progressed assert sim_3 != sim_4 assert sim_4 == sim_5 assert sim_5 != sim_6 # get_cherenkov_shower shower_kwargs = dict( centroid_x=0.1, centroid_y=0, length=0.01, width=0.01, psi=0, time_gradient=1, time_intercept=20, intensity=100, ) sim_1 = simulator_1.get_cherenkov_shower(**shower_kwargs) sim_2 = simulator_2.get_cherenkov_shower(**shower_kwargs) sim_3 = simulator_3.get_cherenkov_shower(**shower_kwargs) sim_4 = simulator_4.get_cherenkov_shower(**shower_kwargs) sim_5 = simulator_5.get_cherenkov_shower(**shower_kwargs) sim_6 = simulator_6.get_cherenkov_shower(**shower_kwargs) assert sim_1 != sim_2 assert sim_2 != sim_3 # Generator has been progressed assert sim_3 != sim_4 assert sim_4 == sim_5 assert sim_5 != sim_6
def test_get_sampled_waveform_sample_width(): camera = Camera( mapping=SSTCameraMapping(n_pixels=1), ) pe = Photoelectrons(pixel=np.array([0]), time=np.array([40]), charge=np.array([1])) acquisition = EventAcquisition(camera=camera, seed=1) readout = acquisition.get_continuous_readout(pe) waveform = acquisition.get_sampled_waveform(readout) print(waveform.max())
def test_get_random_cherenkov_shower(): camera = Camera() simulator = PhotoelectronSource(camera, seed=1) pe = simulator.get_random_cherenkov_shower(cherenkov_pulse_width=5) assert (pe.pixel.size == pe.time.size) & (pe.pixel.size == pe.charge.size) assert pe.pixel.size == 40891 assert (pe.charge > 0).all() np.testing.assert_allclose(pe.charge.sum(), 41032.3, rtol=1e-1) np.testing.assert_allclose(pe.time.mean(), 827.86, rtol=1e-1) np.testing.assert_allclose(pe.time.std(), 5, rtol=1e-1)
def test_get_nsb(): mapping = SSTCameraMapping(n_pixels=2) camera = Camera(mapping=mapping) simulator = PhotoelectronSource(camera, seed=1) nsb = simulator.get_nsb(rate=1000) assert (nsb.pixel.size == nsb.time.size) & (nsb.pixel.size == nsb.charge.size) assert (nsb.pixel == 0).sum() == 1001 assert (nsb.pixel == 1).sum() == 982 assert (nsb.time > 0).all() assert (nsb.charge > 0).all()
def test_get_n_superpixel_triggers(): camera = Camera(mapping=SSTCameraMapping(n_pixels=2)) trigger = NNSuperpixelAboveThreshold(camera=camera) n_superpixels = 2 n_samples = trigger.camera.continuous_readout_time_axis.size trigger_readout = np.zeros((n_superpixels, n_samples), dtype=np.bool) trigger_readout[0, 10] = True trigger_readout[0, 15] = True trigger_readout[1, 100] = True trigger_readout[1, 150] = True trigger_readout[1, 200] = True n_triggers = trigger.get_n_superpixel_triggers(trigger_readout) assert np.array_equal(n_triggers, np.array([2, 3], dtype=np.int))
def test_get_uniform_illumination(): mapping = SSTCameraMapping(n_pixels=2) camera = Camera(mapping=mapping) simulator = PhotoelectronSource(camera, seed=1) pe = simulator.get_uniform_illumination(time=40, illumination=100, laser_pulse_width=2) assert (pe.pixel.size == pe.time.size) & (pe.pixel.size == pe.charge.size) assert (pe.pixel == 0).sum() == 100 assert (pe.pixel == 1).sum() == 94 assert (pe.time > 0).all() assert (pe.charge > 0).all() np.testing.assert_allclose(pe.time.mean(), 40, rtol=1e-1) np.testing.assert_allclose(pe.time.std(), 2, rtol=1e-1)
def test_get_continuous_readout_with_noise(): pulse = GaussianPulse() noise = GaussianNoise(stddev=pulse.peak_height, seed=1) camera = Camera( reference_pulse=pulse, electronic_noise=noise, mapping=SSTCameraMapping(n_pixels=1) ) acquisition = EventAcquisition(camera=camera, seed=1) photoelectrons = Photoelectrons( pixel=np.array([], dtype=np.int), time=np.array([]), charge=np.array([]) ) readout = acquisition.get_continuous_readout(photoelectrons) stddev_pe = readout.std() / camera.reference_pulse.peak_height np.testing.assert_allclose(stddev_pe, 1, rtol=1e-2)
def test_cherenkov(): camera = Camera() pdf, time = get_cherenkov_shower_image( xpix=camera.mapping.pixel.x, ypix=camera.mapping.pixel.y, centroid_x=0, centroid_y=0, length=0.01, width=0.01, psi=0, time_gradient=1, time_intercept=20, ) np.testing.assert_allclose(pdf.sum(), 1) np.testing.assert_allclose(np.polyfit(camera.mapping.pixel.x, time, 1), [1.0, 20.0]) pdf, time = get_cherenkov_shower_image( xpix=camera.mapping.pixel.x, ypix=camera.mapping.pixel.y, centroid_x=0.1, centroid_y=0, length=0.1, width=0.03, psi=360, time_gradient=1, time_intercept=20, ) np.testing.assert_allclose(pdf.sum(), 1) np.testing.assert_allclose(np.polyfit(camera.mapping.pixel.x, time, 1), [1.0, 19.9]) pdf, time = get_cherenkov_shower_image( xpix=camera.mapping.pixel.x, ypix=camera.mapping.pixel.y, centroid_x=0, centroid_y=0, length=0.01, width=0.01, psi=90, time_gradient=1, time_intercept=20, ) np.testing.assert_allclose(pdf.sum(), 1) np.testing.assert_allclose(np.polyfit(camera.mapping.pixel.y, time, 1), [1.0, 20.0])
def test_extend_digital_trigger(): camera = Camera(mapping=SSTCameraMapping(n_pixels=2)) n_pixels = camera.mapping.n_pixels time_axis = camera.continuous_readout_time_axis n_samples = time_axis.size division = camera.continuous_readout_sample_division length = camera.digital_trigger_length * division above_threshold = np.zeros((n_pixels, n_samples), dtype=np.bool) above_threshold[0, 100:101] = True above_threshold[1, 200:500] = True above_threshold[1, 510:520] = True trigger_readout_expected = np.zeros((n_pixels, n_samples), dtype=np.bool) trigger_readout_expected[0, 100:101+length] = True trigger_readout_expected[1, 200:500+length] = True trigger_readout_expected[1, 510:520+length] = True trigger_readout = extend_digital_trigger(above_threshold, length) assert np.array_equal(trigger_readout, trigger_readout_expected)
def test_get_continuous_readout_with_noise(): pulse = GaussianPulse() noise = GaussianNoise(stddev=pulse.height, seed=1) camera = Camera(continuous_readout_duration=1000, n_waveform_samples=1000, photoelectron_pulse=pulse, readout_noise=noise, mapping=SSTCameraMapping(n_pixels=1)) acquisition = EventAcquisition(camera=camera, seed=1) photoelectrons = Photoelectrons(pixel=np.array([], dtype=int), time=np.array([]), charge=np.array([])) readout = acquisition.get_continuous_readout(photoelectrons) stddev_pe = readout.std() / camera.photoelectron_pulse.height np.testing.assert_allclose(stddev_pe, 1, rtol=1e-2) waveform = acquisition.get_sampled_waveform(readout) predicted_stddev = noise.stddev / np.sqrt( camera.continuous_readout_sample_division) np.testing.assert_allclose(waveform.std(), predicted_stddev, rtol=1e-2)
def test_resample_photoelectron_charge(): camera = Camera(mapping=SSTCameraMapping(n_pixels=2), ) pe_0 = Photoelectrons(pixel=np.array([0, 1]), time=np.array([30, 40]), charge=np.array([1.0, 2.0]), metadata=dict(test=2)) source = PhotoelectronSource(camera=camera, seed=1) pe_1 = source.resample_photoelectron_charge(pe_0) pe_2 = source.resample_photoelectron_charge(pe_0) source = PhotoelectronSource(camera=camera, seed=2) pe_3 = source.resample_photoelectron_charge(pe_0) assert np.array_equal(pe_0.pixel, pe_1.pixel) assert np.array_equal(pe_1.pixel, pe_2.pixel) assert np.array_equal(pe_2.pixel, pe_3.pixel) assert np.array_equal(pe_0.time, pe_1.time) assert np.array_equal(pe_1.time, pe_2.time) assert np.array_equal(pe_2.time, pe_3.time) assert not np.array_equal(pe_0.charge, pe_1.charge) assert np.array_equal(pe_1.charge, pe_2.charge) assert not np.array_equal(pe_2.charge, pe_3.charge) assert pe_0.metadata == pe_1.metadata == pe_2.metadata == pe_3.metadata
def test_get_cherenkov_shower(): shower_kwargs = dict( centroid_x=0.1, centroid_y=0, length=0.01, width=0.01, psi=0, time_gradient=0, time_intercept=20, intensity=1000, cherenkov_pulse_width=5, ) camera = Camera() simulator = PhotoelectronSource(camera, seed=1) pe = simulator.get_cherenkov_shower(**shower_kwargs) assert (pe.pixel.size == pe.time.size) & (pe.pixel.size == pe.charge.size) assert pe.pixel.size == 991 assert (pe.charge > 0).all() np.testing.assert_allclose(pe.charge.sum(), 991, rtol=1e-1) np.testing.assert_allclose(pe.time.mean(), 20, rtol=1e-1) np.testing.assert_allclose(pe.time.std(), 5, rtol=1e-1)
def test_update_trigger_threshold(): camera = Camera(trigger_threshold=5) trigger = NNSuperpixelAboveThreshold(camera=camera) assert trigger.camera.trigger_threshold == 5 camera.update_trigger_threshold(6) assert trigger.camera.trigger_threshold == 6
def test_photoelectron_source(): camera = Camera() PhotoelectronSource(camera)
def acquisition(): camera = Camera(mapping=SSTCameraMapping(n_pixels=2)) acquisition = EventAcquisition(camera=camera) return acquisition
def test_camera_image(): camera = Camera() image = CameraImage.from_coordinates(camera.mapping.pixel) assert image.n_pixels == camera.mapping.n_pixels
def acquisition(): camera = Camera(continuous_readout_duration=1000, mapping=SSTCameraMapping(n_pixels=2)) acquisition = EventAcquisition(camera=camera) return acquisition
def test_read_only(): camera = Camera(trigger_threshold=5) assert camera.trigger_threshold == 5 with pytest.raises(FrozenInstanceError): # noinspection PyDataclass camera.trigger_threshold = 6
def test_update_trigger_threshold(): camera = Camera(trigger_threshold=5) assert camera.trigger_threshold == 5 camera.update_trigger_threshold(6) assert camera.trigger_threshold == 6