Example #1
0
def test_global_peak_window_sum(camera_waveforms):
    waveforms, _ = camera_waveforms
    extractor = GlobalPeakWindowSum()
    charge, pulse_time = extractor(waveforms)

    assert_allclose(charge[0][0], 232.559, rtol=1e-3)
    assert_allclose(charge[1][0], 425.406, rtol=1e-3)
    assert_allclose(pulse_time[0][0], 47.823488, rtol=1e-3)
    assert_allclose(pulse_time[1][0], 62.931829, rtol=1e-3)
Example #2
0
def test_global_peak_window_sum_with_pixel_fraction(subarray):
    from ctapipe.image.extractor import GlobalPeakWindowSum

    tel_id = 1
    camera = subarray.tel[tel_id].camera
    sample_rate = camera.readout.sampling_rate.to_value(u.ns**-1)
    n_pixels = camera.geometry.n_pixels
    selected_gain_channel = np.zeros(n_pixels, dtype=np.uint8)

    bright_pixels = np.zeros(n_pixels, dtype=bool)
    bright_pixels[np.random.choice(n_pixels, size=int(0.1 * n_pixels))] = True

    # signal in dim pixels is in slice 10, signal in bright pixels is in slice 30
    waveforms = np.zeros((n_pixels, 50), dtype="float64")
    waveforms[~bright_pixels, 9] = 3
    waveforms[~bright_pixels, 10] = 5
    waveforms[~bright_pixels, 11] = 2
    waveforms[bright_pixels, 29] = 5
    waveforms[bright_pixels, 30] = 10
    waveforms[bright_pixels, 31] = 3

    extractor = GlobalPeakWindowSum(
        subarray=subarray,
        window_width=8,
        window_shift=4,
        pixel_fraction=0.05,
        apply_integration_correction=False,
    )

    dl1 = extractor(waveforms=waveforms,
                    telid=tel_id,
                    selected_gain_channel=selected_gain_channel)

    assert np.allclose(dl1.image[bright_pixels], 18)
    assert np.allclose(dl1.image[~bright_pixels], 0)

    expected = np.average([29, 30, 31], weights=[5, 10, 3])
    assert np.allclose(dl1.peak_time[bright_pixels], expected / sample_rate)
Example #3
0
def test_dl1_charge_calib(example_subarray):
    # copy because we mutate the camera, should not affect other tests
    subarray = deepcopy(example_subarray)
    camera = subarray.tel[1].camera
    # test with a sampling_rate different than 1 to
    # test if we handle time vs. slices correctly
    sampling_rate = 2
    camera.readout.sampling_rate = sampling_rate * u.GHz

    n_pixels = camera.geometry.n_pixels
    n_samples = 96
    mid = n_samples // 2
    pulse_sigma = 6
    random = np.random.RandomState(1)
    x = np.arange(n_samples)

    # Randomize times and create pulses
    time_offset = random.uniform(-10, +10, n_pixels)
    y = norm.pdf(x, mid + time_offset[:, np.newaxis],
                 pulse_sigma).astype("float32")

    camera.readout.reference_pulse_shape = norm.pdf(x, mid,
                                                    pulse_sigma)[np.newaxis, :]
    camera.readout.reference_pulse_sample_width = 1 / camera.readout.sampling_rate

    # Define absolute calibration coefficients
    absolute = random.uniform(100, 1000, n_pixels).astype("float32")
    y *= absolute[:, np.newaxis]

    # Define relative coefficients
    relative = random.normal(1, 0.01, n_pixels)
    y /= relative[:, np.newaxis]

    # Define pedestal
    pedestal = random.uniform(-4, 4, n_pixels)
    y += pedestal[:, np.newaxis]

    event = ArrayEventContainer()
    telid = list(subarray.tel.keys())[0]
    event.dl0.tel[telid].waveform = y
    event.dl0.tel[telid].selected_gain_channel = np.zeros(len(y), dtype=int)
    event.r1.tel[telid].selected_gain_channel = np.zeros(len(y), dtype=int)

    # Test default
    calibrator = CameraCalibrator(
        subarray=subarray, image_extractor=FullWaveformSum(subarray=subarray))
    calibrator(event)
    np.testing.assert_allclose(event.dl1.tel[telid].image, y.sum(1), rtol=1e-4)

    event.calibration.tel[telid].dl1.pedestal_offset = pedestal
    event.calibration.tel[telid].dl1.absolute_factor = absolute
    event.calibration.tel[telid].dl1.relative_factor = relative

    # Test without timing corrections
    calibrator(event)
    dl1 = event.dl1.tel[telid]
    np.testing.assert_allclose(dl1.image, 1, rtol=1e-5)
    expected_peak_time = (mid + time_offset) / sampling_rate
    np.testing.assert_allclose(dl1.peak_time, expected_peak_time, rtol=1e-5)

    # test with timing corrections
    event.calibration.tel[telid].dl1.time_shift = time_offset / sampling_rate
    calibrator(event)

    # more rtol since shifting might lead to reduced integral
    np.testing.assert_allclose(event.dl1.tel[telid].image, 1, rtol=1e-5)
    np.testing.assert_allclose(event.dl1.tel[telid].peak_time,
                               mid / sampling_rate,
                               atol=1)

    # test not applying time shifts
    # now we should be back to the result without setting time shift
    calibrator.apply_peak_time_shift = False
    calibrator.apply_waveform_time_shift = False
    calibrator(event)

    np.testing.assert_allclose(event.dl1.tel[telid].image, 1, rtol=1e-4)
    np.testing.assert_allclose(event.dl1.tel[telid].peak_time,
                               expected_peak_time,
                               atol=1)

    # We now use GlobalPeakWindowSum to see the effect of missing charge
    # due to not correcting time offsets.
    calibrator = CameraCalibrator(
        subarray=subarray,
        image_extractor=GlobalPeakWindowSum(subarray=subarray))
    calibrator(event)
    # test with timing corrections, should work
    # higher rtol because we cannot shift perfectly
    np.testing.assert_allclose(event.dl1.tel[telid].image, 1, rtol=0.01)
    np.testing.assert_allclose(event.dl1.tel[telid].peak_time,
                               mid / sampling_rate,
                               atol=1)

    # test deactivating timing corrections
    calibrator.apply_waveform_time_shift = False
    calibrator(event)

    # make sure we chose an example where the time shifts matter
    # charges should be quite off due to summing around global shift
    assert not np.allclose(event.dl1.tel[telid].image, 1, rtol=0.1)
    assert not np.allclose(
        event.dl1.tel[telid].peak_time, mid / sampling_rate, atol=1)