def test_intersection_weighting_spoiled_parameters():
    """
    Test that the weighting scheme is useful especially when a telescope is 90 deg with respect to the other two
    """
    hill_inter = HillasIntersection()

    delta = 100 * u.m
    tel_x_dict = {1: delta, 2: -delta, 3: -delta}
    tel_y_dict = {1: delta, 2: delta, 3: -delta}

    # telescope 2 have a spoiled reconstruction (45 instead of -45)
    hillas_dict = {
        1: HillasParametersContainer(intensity=10000, psi=-90 * u.deg),
        2: HillasParametersContainer(intensity=1, psi=45 * u.deg),
        3: HillasParametersContainer(intensity=10000, psi=0 * u.deg),
    }

    reco_konrad_spoiled = hill_inter.reconstruct_tilted(
        hillas_parameters=hillas_dict, tel_x=tel_x_dict, tel_y=tel_y_dict)

    np.testing.assert_allclose(reco_konrad_spoiled[0],
                               delta.to_value(u.m),
                               atol=1e-1)
    np.testing.assert_allclose(reco_konrad_spoiled[1],
                               -delta.to_value(u.m),
                               atol=1e-1)
Exemplo n.º 2
0
def test_intersection_reco_impact_point_tilted():
    """
    Function to test the reconstruction of the impact point in the tilted frame.
    This is done using a squared configuration, of which the impact point occupies a vertex,
    ad the three telescopes the other three vertices.
    """
    hill_inter = HillasIntersection()

    delta = 100 * u.m
    tel_x_dict = {1: delta, 2: -delta, 3: -delta}
    tel_y_dict = {1: delta, 2: delta, 3: -delta}

    hillas_dict = {
        1: HillasParametersContainer(intensity=100, psi=-90 * u.deg),
        2: HillasParametersContainer(intensity=100, psi=-45 * u.deg),
        3: HillasParametersContainer(intensity=100, psi=0 * u.deg)
    }

    reco_konrad = hill_inter.reconstruct_tilted(
        hillas_parameters=hillas_dict,
        tel_x=tel_x_dict,
        tel_y=tel_y_dict
    )

    np.testing.assert_allclose(reco_konrad[0], delta.to_value(u.m), atol=1e-8)
    np.testing.assert_allclose(reco_konrad[1], -delta.to_value(u.m), atol=1e-8)
Exemplo n.º 3
0
def test_intersection_nominal_reconstruction():
    """
    Testing the reconstruction of the position in the nominal frame with a three-telescopes system.
    This is done using a squared configuration, of which the impact point occupies a vertex,
    ad the three telescopes the other three vertices.
    """
    hill_inter = HillasIntersection()

    delta = 1.0 * u.m
    horizon_frame = AltAz()
    altitude = 70 * u.deg
    azimuth = 10 * u.deg

    array_direction = SkyCoord(alt=altitude,
                               az=azimuth,
                               frame=horizon_frame)

    nominal_frame = NominalFrame(origin=array_direction)

    focal_length = 28 * u.m

    camera_frame = CameraFrame(focal_length=focal_length,
                               telescope_pointing=array_direction)

    cog_coords_camera_1 = SkyCoord(x=delta, y=0 * u.m, frame=camera_frame)
    cog_coords_camera_2 = SkyCoord(x=delta / 0.7, y=delta / 0.7, frame=camera_frame)
    cog_coords_camera_3 = SkyCoord(x=0 * u.m, y=delta, frame=camera_frame)

    cog_coords_nom_1 = cog_coords_camera_1.transform_to(nominal_frame)
    cog_coords_nom_2 = cog_coords_camera_2.transform_to(nominal_frame)
    cog_coords_nom_3 = cog_coords_camera_3.transform_to(nominal_frame)

    #  x-axis is along the altitude and y-axis is along the azimuth
    hillas_1 = HillasParametersContainer(x=cog_coords_nom_1.delta_alt,
                                         y=cog_coords_nom_1.delta_az,
                                         intensity=100,
                                         psi=0 * u.deg)

    hillas_2 = HillasParametersContainer(x=cog_coords_nom_2.delta_alt,
                                         y=cog_coords_nom_2.delta_az,
                                         intensity=100,
                                         psi=45 * u.deg)

    hillas_3 = HillasParametersContainer(x=cog_coords_nom_3.delta_alt,
                                         y=cog_coords_nom_3.delta_az,
                                         intensity=100,
                                         psi=90 * u.deg)

    hillas_dict = {1: hillas_1, 2: hillas_2, 3: hillas_3}

    reco_nominal = hill_inter.reconstruct_nominal(hillas_parameters=hillas_dict)

    nominal_pos = SkyCoord(
        delta_az=u.Quantity(reco_nominal[0], u.rad),
        delta_alt=u.Quantity(reco_nominal[1], u.rad),
        frame=nominal_frame
    )

    np.testing.assert_allclose(nominal_pos.altaz.az.to_value(u.deg), azimuth.to_value(u.deg), atol=1e-8)
    np.testing.assert_allclose(nominal_pos.altaz.alt.to_value(u.deg), altitude.to_value(u.deg), atol=1e-8)
Exemplo n.º 4
0
def test_array_display():
    """ check that we can do basic array display functionality """
    from ctapipe.visualization.mpl_array import ArrayDisplay
    from ctapipe.image import timing_parameters

    # build a test subarray:
    tels = dict()
    tel_pos = dict()
    for ii, pos in enumerate([[0, 0, 0], [100, 0, 0], [-100, 0, 0]] * u.m):
        tels[ii + 1] = TelescopeDescription.from_name("MST", "NectarCam")
        tel_pos[ii + 1] = pos

    sub = SubarrayDescription(name="TestSubarray",
                              tel_positions=tel_pos,
                              tel_descriptions=tels)

    ad = ArrayDisplay(sub)
    ad.set_vector_rho_phi(1 * u.m, 90 * u.deg)

    # try setting a value
    vals = ones(sub.num_tels)
    ad.values = vals

    assert (vals == ad.values).all()

    # test using hillas params:
    hillas_dict = {
        1: HillasParametersContainer(length=100.0 * u.m, psi=90 * u.deg),
        2: HillasParametersContainer(length=20000 * u.cm, psi="95deg"),
    }

    grad = 2
    intercept = 1

    geom = CameraGeometry.from_name("LSTCam")
    rot_angle = 20 * u.deg
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=rot_angle)

    timing_rot20 = timing_parameters(
        geom,
        image=ones(geom.n_pixels),
        peak_time=intercept + grad * geom.pix_x.value,
        hillas_parameters=hillas,
        cleaning_mask=ones(geom.n_pixels, dtype=bool),
    )
    gradient_dict = {
        1: timing_rot20.slope.value,
        2: timing_rot20.slope.value,
    }
    ad.set_vector_hillas(
        hillas_dict=hillas_dict,
        length=500,
        time_gradient=gradient_dict,
        angle_offset=0 * u.deg,
    )

    ad.set_line_hillas(hillas_dict, range=300)
    ad.add_labels()
    ad.remove_labels()
def test_intersection_xmax_reco():
    """
    Test the reconstruction of xmax with two LSTs that are pointing at zenith = 0.
    The telescopes are places along the x and y axis at the same distance from the center.
    The impact point is hard-coded to be happening in the center of this cartesian system.
    """
    hill_inter = HillasIntersection()

    horizon_frame = AltAz()
    zen_pointing = 10 * u.deg

    array_direction = SkyCoord(alt=90 * u.deg - zen_pointing,
                               az=0 * u.deg,
                               frame=horizon_frame)
    nom_frame = NominalFrame(origin=array_direction)

    source_sky_pos_reco = SkyCoord(alt=90 * u.deg - zen_pointing,
                                   az=0 * u.deg,
                                   frame=horizon_frame)

    nom_pos_reco = source_sky_pos_reco.transform_to(nom_frame)
    delta = 1.0 * u.m

    # LST focal length
    focal_length = 28 * u.m

    hillas_dict = {
        1:
        HillasParametersContainer(
            x=-(delta / focal_length) * u.rad,
            y=((0 * u.m) / focal_length) * u.rad,
            intensity=1,
        ),
        2:
        HillasParametersContainer(
            x=((0 * u.m) / focal_length) * u.rad,
            y=-(delta / focal_length) * u.rad,
            intensity=1,
        ),
    }

    x_max = hill_inter.reconstruct_xmax(
        source_x=nom_pos_reco.fov_lon,
        source_y=nom_pos_reco.fov_lat,
        core_x=0 * u.m,
        core_y=0 * u.m,
        hillas_parameters=hillas_dict,
        tel_x={
            1: (150 * u.m),
            2: (0 * u.m)
        },
        tel_y={
            1: (0 * u.m),
            2: (150 * u.m)
        },
        zen=zen_pointing,
    )
    print(x_max)
Exemplo n.º 6
0
def test_read_without_prefixes(tmp_path):
    path = tmp_path / "test.h5"

    hillas_parameter_container = HillasParametersContainer(fov_lon=1 * u.deg,
                                                           fov_lat=1 * u.deg,
                                                           length=1 * u.deg,
                                                           width=1 * u.deg)

    leakage_container = LeakageContainer(
        pixels_width_1=0.1,
        pixels_width_2=0.1,
        intensity_width_1=0.1,
        intensity_width_2=0.1,
    )

    with HDF5TableWriter(path, group_name="dl1", add_prefix=False) as writer:
        writer.write("params", (hillas_parameter_container, leakage_container))

    df = pd.read_hdf(path, key="/dl1/params")
    assert "fov_lon" in df.columns
    assert "pixels_width_1" in df.columns

    # call with prefixes=False
    with HDF5TableReader(path) as reader:
        generator = reader.read(
            "/dl1/params",
            (HillasParametersContainer, LeakageContainer),
            prefixes=False,
        )
        hillas_, leakage_ = next(generator)

    for value, read_value in zip(leakage_container.as_dict().values(),
                                 leakage_.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    for value, read_value in zip(hillas_parameter_container.as_dict().values(),
                                 hillas_.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    # call with manually removed prefixes
    with HDF5TableReader(path) as reader:
        generator = reader.read(
            "/dl1/params",
            (HillasParametersContainer, LeakageContainer),
            prefixes=["", ""],
        )
        hillas_, leakage_ = next(generator)

    for value, read_value in zip(leakage_container.as_dict().values(),
                                 leakage_.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    for value, read_value in zip(hillas_parameter_container.as_dict().values(),
                                 hillas_.as_dict().values()):
        np.testing.assert_equal(value, read_value)
Exemplo n.º 7
0
def test_read_multiple_containers(tmp_path):
    path = tmp_path / "test_append.h5"
    hillas_parameter_container = HillasParametersContainer(fov_lon=1 * u.deg,
                                                           fov_lat=1 * u.deg,
                                                           length=1 * u.deg,
                                                           width=1 * u.deg)

    leakage_container = LeakageContainer(
        pixels_width_1=0.1,
        pixels_width_2=0.1,
        intensity_width_1=0.1,
        intensity_width_2=0.1,
    )
    with HDF5TableWriter(path, group_name="dl1", add_prefix=True) as writer:
        writer.write("params", [hillas_parameter_container, leakage_container])

    df = pd.read_hdf(path, key="/dl1/params")
    assert "hillas_fov_lon" in df.columns
    assert "leakage_pixels_width_1" in df.columns

    # test reading both containers separately
    with HDF5TableReader(path) as reader:
        generator = reader.read("/dl1/params",
                                HillasParametersContainer,
                                prefixes=True)
        hillas = next(generator)
    for value, read_value in zip(hillas_parameter_container.as_dict().values(),
                                 hillas.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    with HDF5TableReader(path) as reader:
        generator = reader.read("/dl1/params", LeakageContainer, prefixes=True)
        leakage = next(generator)
    for value, read_value in zip(leakage_container.as_dict().values(),
                                 leakage.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    # test reading both containers simultaneously
    with HDF5TableReader(path) as reader:
        generator = reader.read(
            "/dl1/params",
            (HillasParametersContainer, LeakageContainer),
            prefixes=True,
        )
        hillas_, leakage_ = next(generator)

    for value, read_value in zip(leakage_container.as_dict().values(),
                                 leakage_.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    for value, read_value in zip(hillas_parameter_container.as_dict().values(),
                                 hillas_.as_dict().values()):
        np.testing.assert_equal(value, read_value)
Exemplo n.º 8
0
def test_read_duplicated_container_types(tmp_path):
    path = tmp_path / "test.h5"

    hillas_config_1 = HillasParametersContainer(
        x=1 * u.m, y=2 * u.m, length=3 * u.m, width=4 * u.m, prefix="hillas_1"
    )
    hillas_config_2 = HillasParametersContainer(
        x=2 * u.m, y=3 * u.m, length=4 * u.m, width=5 * u.m, prefix="hillas_2"
    )

    with HDF5TableWriter(path, group_name="dl1", add_prefix=True) as writer:
        writer.write("params", [hillas_config_1, hillas_config_2])

    df = pd.read_hdf(path, key="/dl1/params")
    assert "hillas_1_x" in df.columns
    assert "hillas_2_x" in df.columns

    with HDF5TableReader(path) as reader:
        generator = reader.read(
            "/dl1/params",
            [HillasParametersContainer(), HillasParametersContainer()],
            prefixes=["hillas_1", "hillas_2"],
        )
        hillas_1, hillas_2 = next(generator)

    for value, read_value in zip(
        hillas_config_1.as_dict().values(), hillas_1.as_dict().values()
    ):
        np.testing.assert_equal(value, read_value)

    for value, read_value in zip(
        hillas_config_2.as_dict().values(), hillas_2.as_dict().values()
    ):
        np.testing.assert_equal(value, read_value)
Exemplo n.º 9
0
def test_ignore_negative():
    from ctapipe.image import timing_parameters
    grad = 2.0
    intercept = 1.0
    deviation = 0.1

    geom = CameraGeometry.from_name("LSTCam")
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=0 * u.deg)

    random = np.random.RandomState(1)
    peak_time = intercept + grad * geom.pix_x.value
    peak_time += random.normal(0, deviation, geom.n_pixels)

    image = np.ones(geom.n_pixels)
    image[5:10] = -1.0

    cleaning_mask = image >= 0

    timing = timing_parameters(
        geom,
        image,
        peak_time=peak_time,
        hillas_parameters=hillas,
        cleaning_mask=cleaning_mask,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit, rtol=1e-2)
    assert_allclose(timing.intercept, intercept, rtol=1e-2)
    assert_allclose(timing.deviation, deviation, rtol=1e-2)
Exemplo n.º 10
0
def test_psi_0():
    from ctapipe.image import timing_parameters
    """
    Simple test that gradient fitting gives expected answers for perfect
    gradient
    """
    grad = 2.0
    intercept = 1.0
    deviation = 0.1

    geom = CameraGeometry.from_name("LSTCam")
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=0 * u.deg)

    random = np.random.RandomState(1)
    peak_time = intercept + grad * geom.pix_x.value
    peak_time += random.normal(0, deviation, geom.n_pixels)

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peak_time=peak_time,
        hillas_parameters=hillas,
        cleaning_mask=np.ones(geom.n_pixels, dtype=bool)
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit, rtol=1e-2)
    assert_allclose(timing.intercept, intercept, rtol=1e-2)
    assert_allclose(timing.deviation, deviation, rtol=1e-2)
Exemplo n.º 11
0
def test_psi_20():
    from ctapipe.image import timing_parameters

    # Then try a different rotation angle
    grad = 2
    intercept = 1
    deviation = 0.1

    geom = CameraGeometry.from_name("LSTCam")
    psi = 20 * u.deg
    hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=psi)

    random = np.random.RandomState(1)
    peak_time = intercept + grad * (np.cos(psi) * geom.pix_x.value
                                     + np.sin(psi) * geom.pix_y.value)
    peak_time += random.normal(0, deviation, geom.n_pixels)

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peak_time=peak_time,
        hillas_parameters=hillas,
        cleaning_mask=np.ones(geom.n_pixels, dtype=bool)
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit, rtol=1e-2)
    assert_allclose(timing.intercept, intercept, rtol=1e-2)
    assert_allclose(timing.deviation, deviation, rtol=1e-2)
Exemplo n.º 12
0
def test_append_container(tmp_path):
    path = tmp_path / "test_append.h5"
    with HDF5TableWriter(path, mode="w") as writer:
        for event_id in range(10):
            hillas = HillasParametersContainer()
            index = TelEventIndexContainer(obs_id=1, event_id=event_id, tel_id=1)
            writer.write("data", [index, hillas])

    with HDF5TableWriter(path, mode="a") as writer:
        for event_id in range(10):
            index = TelEventIndexContainer(obs_id=2, event_id=event_id, tel_id=1)
            hillas = HillasParametersContainer()
            writer.write("data", [index, hillas])

    table = read_table(path, "/data")
    assert len(table) == 20
    assert np.all(table["obs_id"] == np.repeat([1, 2], 10))
    assert np.all(table["event_id"] == np.tile(np.arange(10), 2))
Exemplo n.º 13
0
def test_custom_prefix():
    container = HillasParametersContainer(
        x=1 * u.m, y=1 * u.m, length=1 * u.m, width=1 * u.m
    )
    container.prefix = "custom"
    with tempfile.NamedTemporaryFile() as f:
        with HDF5TableWriter(f.name, group_name="dl1", add_prefix=True) as writer:
            writer.write("params", container)

        with HDF5TableReader(f.name) as reader:
            generator = reader.read(
                "/dl1/params", HillasParametersContainer(), prefixes="custom"
            )
            read_container = next(generator)
        assert isinstance(read_container, HillasParametersContainer)
        for value, read_value in zip(
            container.as_dict().values(), read_container.as_dict().values()
        ):
            np.testing.assert_equal(value, read_value)
Exemplo n.º 14
0
def test_invalid_events(subarray_and_event_gamma_off_axis_500_gev):
    """
    The HillasReconstructor is supposed to fail
    in these cases:
    - less than two teleskopes
    - any width is NaN
    - any width is 0

    This test takes 1 shower from a test simtel file and modifies a-posteriori
    some hillas dictionaries to make it non-reconstructable.
    It is supposed to fail if no Exception or another Exception gets thrown.
    """

    # 4-LST bright event already calibrated
    # we'll clean it and parametrize it again in the TelescopeFrame
    subarray, event = subarray_and_event_gamma_off_axis_500_gev
    calib = CameraCalibrator(subarray)
    image_processor = ImageProcessor(subarray)

    # perform no quality cuts, so we can see if our additional checks on valid
    # input work
    config = Config({"StereoQualityQuery": {
        "quality_criteria": [],
    }})
    hillas_reconstructor = HillasReconstructor(subarray, config=config)

    calib(event)
    image_processor(event)

    result = hillas_reconstructor(event)
    assert result.is_valid

    # copy event container to modify it
    invalid_event = deepcopy(event)

    # overwrite all image parameters but the last one with dummy ones
    for tel_id in list(invalid_event.dl1.tel.keys())[:-1]:
        invalid_event.dl1.tel[
            tel_id].parameters.hillas = HillasParametersContainer()

    result = hillas_reconstructor(invalid_event)
    assert not result.is_valid

    tel_id = list(invalid_event.dl1.tel.keys())[-1]
    # Now use the original event, but overwrite the last width to 0
    invalid_event = deepcopy(event)
    invalid_event.dl1.tel[tel_id].parameters.hillas.width = 0 * u.m
    result = hillas_reconstructor(invalid_event)
    assert not result.is_valid

    # Now use the original event, but overwrite the last width to NaN
    invalid_event = deepcopy(event)
    invalid_event.dl1.tel[tel_id].parameters.hillas.width = np.nan * u.m
    result = hillas_reconstructor(invalid_event)
    assert not result.is_valid
Exemplo n.º 15
0
def test_custom_prefix(tmp_path):
    path = tmp_path / "test.h5"

    container = HillasParametersContainer(fov_lon=1 * u.deg,
                                          fov_lat=1 * u.deg,
                                          length=1 * u.deg,
                                          width=1 * u.deg)
    container.prefix = "custom"
    with HDF5TableWriter(path, group_name="dl1", add_prefix=True) as writer:
        writer.write("params", container)

    with HDF5TableReader(path) as reader:
        generator = reader.read("/dl1/params",
                                HillasParametersContainer(),
                                prefixes="custom")
        read_container = next(generator)
    assert isinstance(read_container, HillasParametersContainer)
    for value, read_value in zip(container.as_dict().values(),
                                 read_container.as_dict().values()):
        np.testing.assert_equal(value, read_value)
Exemplo n.º 16
0
def test_hillas_overlay():
    from ctapipe.visualization import CameraDisplay

    disp = CameraDisplay(CameraGeometry.from_name("LSTCam"))
    hillas = HillasParametersContainer(x=0.1 * u.m,
                                       y=-0.1 * u.m,
                                       length=0.5 * u.m,
                                       width=0.2 * u.m,
                                       psi=90 * u.deg)

    disp.overlay_moments(hillas)
Exemplo n.º 17
0
def test_read_multiple_containers():
    hillas_parameter_container = HillasParametersContainer(x=1 * u.m,
                                                           y=1 * u.m,
                                                           length=1 * u.m,
                                                           width=1 * u.m)

    leakage_container = LeakageContainer(
        pixels_width_1=0.1,
        pixels_width_2=0.1,
        intensity_width_1=0.1,
        intensity_width_2=0.1,
    )
    with tempfile.NamedTemporaryFile() as f:
        with HDF5TableWriter(f.name, group_name="dl1",
                             add_prefix=True) as writer:
            writer.write("params",
                         [hillas_parameter_container, leakage_container])

        df = pd.read_hdf(f.name, key="/dl1/params")
        assert "hillas_x" in df.columns
        assert "leakage_pixels_width_1" in df.columns

        # test reading both containers separately
        with HDF5TableReader(f.name) as reader:
            generator = reader.read("/dl1/params",
                                    HillasParametersContainer(),
                                    prefixes=True)
            hillas = next(generator)
        for value, read_value in zip(
                hillas_parameter_container.as_dict().values(),
                hillas.as_dict().values()):
            np.testing.assert_equal(value, read_value)

        with HDF5TableReader(f.name) as reader:
            generator = reader.read("/dl1/params",
                                    LeakageContainer(),
                                    prefixes=True)
            leakage = next(generator)
        for value, read_value in zip(leakage_container.as_dict().values(),
                                     leakage.as_dict().values()):
            np.testing.assert_equal(value, read_value)

        # test reading both containers simultaneously
        with HDF5TableReader(f.name) as reader:
            generator = reader.read(
                "/dl1/params",
                [HillasParametersContainer(),
                 LeakageContainer()],
                prefixes=True,
            )
            hillas_, leakage_ = next(generator)

        for value, read_value in zip(leakage_container.as_dict().values(),
                                     leakage_.as_dict().values()):
            np.testing.assert_equal(value, read_value)

        for value, read_value in zip(
                hillas_parameter_container.as_dict().values(),
                hillas_.as_dict().values()):
            np.testing.assert_equal(value, read_value)
Exemplo n.º 18
0
def test_prefix(tmp_path):
    tmp_file = tmp_path / "test_prefix.hdf5"
    hillas_parameter_container = HillasParametersContainer(x=1 * u.m,
                                                           y=1 * u.m,
                                                           length=1 * u.m,
                                                           width=1 * u.m)

    leakage_container = LeakageContainer(
        pixels_width_1=0.1,
        pixels_width_2=0.1,
        intensity_width_1=0.1,
        intensity_width_2=0.1,
    )

    with HDF5TableWriter(tmp_file.name, group_name="blabla",
                         add_prefix=True) as writer:
        writer.write("events", [hillas_parameter_container, leakage_container])

    df = pd.read_hdf(tmp_file.name, key="/blabla/events")
    assert "hillas_x" in df.columns
    assert "leakage_pixels_width_1" in df.columns

    with HDF5TableReader(tmp_file.name) as reader:
        generator = reader.read("/blabla/events",
                                HillasParametersContainer(),
                                prefix=True)
        hillas = next(generator)
    for value, read_value in zip(hillas_parameter_container.as_dict().values(),
                                 hillas.as_dict().values()):
        np.testing.assert_equal(value, read_value)

    with HDF5TableReader(tmp_file.name) as reader:
        generator = reader.read("/blabla/events",
                                LeakageContainer(),
                                prefix=True)
        leakage = next(generator)
    for value, read_value in zip(leakage_container.as_dict().values(),
                                 leakage.as_dict().values()):
        np.testing.assert_equal(value, read_value)
Exemplo n.º 19
0
    def setup_class(self):
        self.impact_reco = ImPACTReconstructor(root_dir=".")
        self.horizon_frame = AltAz()

        self.h1 = HillasParametersContainer(x=1 * u.deg,
                                            y=1 * u.deg,
                                            r=1 * u.deg,
                                            phi=Angle(0 * u.rad),
                                            intensity=100,
                                            length=0.4 * u.deg,
                                            width=0.4 * u.deg,
                                            psi=Angle(0 * u.rad),
                                            skewness=0,
                                            kurtosis=0)
Exemplo n.º 20
0
def test_read_without_prefixes():
    hillas_parameter_container = HillasParametersContainer(
        x=1 * u.m, y=1 * u.m, length=1 * u.m, width=1 * u.m
    )

    leakage_container = LeakageContainer(
        pixels_width_1=0.1,
        pixels_width_2=0.1,
        intensity_width_1=0.1,
        intensity_width_2=0.1,
    )
    with tempfile.NamedTemporaryFile() as f:
        with HDF5TableWriter(f.name, group_name="dl1", add_prefix=False) as writer:
            writer.write("params", [hillas_parameter_container, leakage_container])

        df = pd.read_hdf(f.name, key="/dl1/params")
        assert "x" in df.columns
        assert "pixels_width_1" in df.columns

        # call with prefixes=False
        with HDF5TableReader(f.name) as reader:
            generator = reader.read(
                "/dl1/params",
                [HillasParametersContainer(), LeakageContainer()],
                prefixes=False,
            )
            hillas_, leakage_ = next(generator)

        for value, read_value in zip(
            leakage_container.as_dict().values(), leakage_.as_dict().values()
        ):
            np.testing.assert_equal(value, read_value)

        for value, read_value in zip(
            hillas_parameter_container.as_dict().values(), hillas_.as_dict().values()
        ):
            np.testing.assert_equal(value, read_value)

        # call with manually removed prefixes
        with HDF5TableReader(f.name) as reader:
            generator = reader.read(
                "/dl1/params",
                [HillasParametersContainer(prefix=""), LeakageContainer(prefix="")],
                prefixes=True,
            )
            hillas_, leakage_ = next(generator)

        for value, read_value in zip(
            leakage_container.as_dict().values(), leakage_.as_dict().values()
        ):
            np.testing.assert_equal(value, read_value)

        for value, read_value in zip(
            hillas_parameter_container.as_dict().values(), hillas_.as_dict().values()
        ):
            np.testing.assert_equal(value, read_value)
Exemplo n.º 21
0
def test_prefix(tmp_path):
    tmp_file = tmp_path / "test_prefix.hdf5"
    hillas_parameter_container = HillasParametersContainer(
        x=1 * u.m, y=1 * u.m, length=1 * u.m, width=1 * u.m
    )

    leakage_container = LeakageContainer(
        pixels_width_1=0.1,
        pixels_width_2=0.1,
        intensity_width_1=0.1,
        intensity_width_2=0.1,
    )

    with HDF5TableWriter(tmp_file.name, group_name="blabla", add_prefix=True) as writer:
        writer.write("events", [hillas_parameter_container, leakage_container])

    df = pd.read_hdf(tmp_file.name, key="/blabla/events")
    assert "hillas_x" in df.columns
    assert "leakage_pixels_width_1" in df.columns
Exemplo n.º 22
0
def test_read_duplicated_container_types():
    hillas_config_1 = HillasParametersContainer(
        x=1 * u.m,
        y=2 * u.m,
        length=3 * u.m,
        width=4 * u.m,
        prefix='hillas_1',
    )
    hillas_config_2 = HillasParametersContainer(
        x=2 * u.m,
        y=3 * u.m,
        length=4 * u.m,
        width=5 * u.m,
        prefix='hillas_2',
    )

    with tempfile.NamedTemporaryFile() as f:
        with HDF5TableWriter(f.name, group_name="dl1",
                             add_prefix=True) as writer:
            writer.write("params", [hillas_config_1, hillas_config_2])

        df = pd.read_hdf(f.name, key="/dl1/params")
        assert "hillas_1_x" in df.columns
        assert "hillas_2_x" in df.columns

        with HDF5TableReader(f.name) as reader:
            generator = reader.read(
                "/dl1/params",
                [HillasParametersContainer(),
                 HillasParametersContainer()],
                prefixes=['hillas_1', 'hillas_2'])
            hillas_1, hillas_2 = next(generator)

        for value, read_value in zip(hillas_config_1.as_dict().values(),
                                     hillas_1.as_dict().values()):
            np.testing.assert_equal(value, read_value)

        for value, read_value in zip(hillas_config_2.as_dict().values(),
                                     hillas_2.as_dict().values()):
            np.testing.assert_equal(value, read_value)
Exemplo n.º 23
0
    def _generator(self):
        """
        Stereo event generator. Yields DataContainer instances, filled
        with the read event data.

        Returns
        -------

        """
        counter = 0
        data = DataContainer()
        data.meta['origin'] = "MAGIC"
        data.meta['input_url'] = self.input_url
        data.meta['is_simulation'] = True
        data.mcheader = self._mc_header

        if self.calib_M1 is not None and self.calib_M2 is not None:
            #Reading data from root file for Events table
            eventid_M1 = np.asarray(
                self.calib_M1["MRawEvtHeader.fStereoEvtNumber"].array())
            eventid_M2 = np.asarray(
                self.calib_M2["MRawEvtHeader.fStereoEvtNumber"].array())
            zenith = np.asarray(self.calib_M1["MMcEvt.fTheta"].array())
            pointing_altitude = np.asarray(
                self.calib_M1["MPointingPos.fZd"].array())
            azimuth = np.asarray(self.calib_M1["MMcEvt.fPhi"].array())
            pointing_azimuth = np.asarray(
                self.calib_M1["MPointingPos.fAz"].array())
            core_x = np.asarray(self.calib_M1["MMcEvt.fCoreX"].array())
            core_y = np.asarray(self.calib_M1["MMcEvt.fCoreY"].array())
            mc_energy = np.asarray(
                self.calib_M1["MMcEvt.fEnergy"].array()) / 1000.0
            h_first_int = np.asarray(
                self.calib_M1["MMcEvt.fZFirstInteraction"].array())

            #Reading data from root file for Image table
            charge_M1 = np.asarray(
                self.calib_M1["MCerPhotEvt.fPixels.fPhot"].array())
            peak_time_M1 = np.asarray(
                self.calib_M1["MArrivalTime.fData"].array())
            charge_M2 = np.asarray(
                self.calib_M2["MCerPhotEvt.fPixels.fPhot"].array())
            peak_time_M2 = np.asarray(
                self.calib_M2["MArrivalTime.fData"].array())

        if self.superstar is not None:
            #Reading data from root file for Events table
            eventid_M1 = np.asarray(
                self.superstar["MRawEvtHeader_1.fStereoEvtNumber"].array())
            eventid_M2 = np.asarray(
                self.superstar["MRawEvtHeader_2.fStereoEvtNumber"].array())
            zenith = np.asarray(self.superstar["MMcEvt_1.fTheta"].array())
            pointing_altitude = np.asarray(
                self.superstar["MPointingPos_1.fZd"].array())
            azimuth = np.asarray(self.superstar["MMcEvt_1.fPhi"].array())
            pointing_azimuth = np.asarray(
                self.superstar["MPointingPos_1.fAz"].array())
            core_x = np.asarray(self.superstar["MMcEvt_1.fCoreX"].array())
            core_y = np.asarray(self.superstar["MMcEvt_1.fCoreY"].array())
            mc_energy = np.asarray(
                self.superstar["MMcEvt_1.fEnergy"].array()) / 1000.0
            h_first_int = np.asarray(
                self.superstar["MMcEvt_1.fZFirstInteraction"].array())

            #Reading data from root file for Parameter table
            hillas_intensity_M1 = np.asarray(
                self.superstar["MHillas_1.fSize"].array())
            hillas_intensity_M2 = np.asarray(
                self.superstar["MHillas_2.fSize"].array())
            hillas_x_M1 = np.asarray(
                self.superstar["MHillas_1.fMeanX"].array())
            hillas_x_M2 = np.asarray(
                self.superstar["MHillas_2.fMeanX"].array())
            hillas_y_M1 = np.asarray(
                self.superstar["MHillas_1.fMeanY"].array())
            hillas_y_M2 = np.asarray(
                self.superstar["MHillas_2.fMeanY"].array())
            hillas_r_M1 = np.sqrt(
                np.power(hillas_x_M1, 2) + np.power(hillas_y_M1, 2))
            hillas_r_M2 = np.sqrt(
                np.power(hillas_x_M2, 2) + np.power(hillas_y_M2, 2))
            hillas_phi_M1 = np.arctan2(hillas_y_M1, hillas_x_M1)
            hillas_phi_M2 = np.arctan2(hillas_y_M2, hillas_x_M2)
            hillas_length_M1 = np.asarray(
                self.superstar["MHillas_1.fLength"].array())
            hillas_length_M2 = np.asarray(
                self.superstar["MHillas_2.fLength"].array())
            hillas_width_M1 = np.asarray(
                self.superstar["MHillas_1.fWidth"].array())
            hillas_width_M2 = np.asarray(
                self.superstar["MHillas_2.fWidth"].array())
            hillas_psi_M1 = np.asarray(
                self.superstar["MHillas_1.fDelta"].array())
            hillas_psi_M2 = np.asarray(
                self.superstar["MHillas_2.fDelta"].array())
            hillas_skewness_M1 = np.asarray(
                self.superstar["MHillasExt_1.fM3Long"].array())
            hillas_skewness_M2 = np.asarray(
                self.superstar["MHillasExt_2.fM3Long"].array())

            leakage_intensity_1_M1 = np.asarray(
                self.superstar["MNewImagePar_1.fLeakage1"].array())
            leakage_intensity_1_M2 = np.asarray(
                self.superstar["MNewImagePar_2.fLeakage1"].array())
            leakage_intensity_2_M1 = np.asarray(
                self.superstar["MNewImagePar_1.fLeakage2"].array())
            leakage_intensity_2_M2 = np.asarray(
                self.superstar["MNewImagePar_2.fLeakage2"].array())

            num_islands_M1 = np.asarray(
                self.superstar["MCerPhotEvt_1.fNumIslands"].array())
            num_islands_M2 = np.asarray(
                self.superstar["MCerPhotEvt_2.fNumIslands"].array())

            #Reading data from root file for Image table (peak time and image mask not )
            charge_M1 = np.asarray(
                self.superstar["MCerPhotEvt_1.fPixels.fPhot"].array())
            peak_time_M1 = np.zeros((charge_M1.shape[0], 1039))
            image_mask_M1 = np.zeros((charge_M1.shape[0], 1039), dtype=bool)
            charge_M2 = np.asarray(
                self.superstar["MCerPhotEvt_2.fPixels.fPhot"].array())
            peak_time_M2 = np.zeros((charge_M2.shape[0], 1039))
            image_mask_M2 = np.zeros((charge_M2.shape[0], 1039), dtype=bool)

        # Get the shower primary id
        shower_primary_id = 1
        if self.file_list[0].split("/")[-1].startswith("GA"):
            shower_primary_id = 1

        #Iterating over all events, and saving only stereo ones
        total_events = min(len(charge_M1), len(charge_M2))
        tels_with_data = {1, 2}
        for i in range(0, total_events):
            if eventid_M1[i] != 0:
                obs_id = self.run_number
                event_id = eventid_M1[i]
                i2 = np.where(eventid_M2 == eventid_M1[i])
                i2 = i2[0].astype(int)
                data.count = counter

                # Setting up the Data container
                data.index.obs_id = obs_id
                data.index.event_id = event_id
                data.r0.tel.clear()
                data.r1.tel.clear()
                data.dl0.tel.clear()

                # Adding the array pointing in the pointing container
                data.pointing.array_altitude = u.Quantity(
                    np.deg2rad(90.0 - pointing_altitude[i]), u.rad)
                data.pointing.array_azimuth = u.Quantity(
                    np.deg2rad(pointing_azimuth[i]), u.rad)

                # Filling the DL1 container with the event data
                for tel_id in tels_with_data:
                    #Adding telescope pointing container
                    data.pointing.tel[tel_id].azimuth = u.Quantity(
                        np.deg2rad(pointing_azimuth[i]), u.rad)
                    data.pointing.tel[tel_id].altitude = u.Quantity(
                        np.deg2rad(90.0 - pointing_altitude[i]), u.rad)

                    #Adding MC data
                    data.mc.alt = Angle(np.pi / 2.0 - zenith[i], u.rad)
                    data.mc.az = Angle(
                        np.deg2rad(180.0 - 7.0) - azimuth[i], u.rad)
                    data.mc.x_max = u.Quantity(0, X_MAX_UNIT)
                    data.mc.h_first_int = u.Quantity(h_first_int[i], u.m)
                    data.mc.core_x = u.Quantity(core_x[i], u.m)
                    data.mc.core_y = u.Quantity(core_y[i], u.m)
                    data.mc.energy = u.Quantity(mc_energy[i], u.TeV)
                    data.mc.shower_primary_id = shower_primary_id

                    if self.superstar is not None:
                        leakage_values = LeakageContainer()
                        hillas_parameters_values = HillasParametersContainer()
                        concentration_values = ConcentrationContainer()
                        timing_values = TimingParametersContainer()
                        morphology_values = MorphologyContainer()

                    # Adding charge, peak time and parameters
                    if tel_id == 1:
                        data.dl1.tel[tel_id].image = charge_M1[i][:1039]
                        data.dl1.tel[tel_id].peak_time = peak_time_M1[i][:1039]
                        if self.superstar is not None:
                            data.dl1.tel[tel_id].image_mask = image_mask_M1[
                                i][:1039]

                            hillas_parameters_values[
                                "intensity"] = hillas_intensity_M1[i]
                            hillas_parameters_values["x"] = u.Quantity(
                                hillas_x_M1[i], unit=u.mm)
                            hillas_parameters_values["y"] = u.Quantity(
                                hillas_y_M1[i], unit=u.mm)
                            hillas_parameters_values["r"] = u.Quantity(
                                hillas_r_M1[i], unit=u.mm)
                            hillas_parameters_values["phi"] = u.Quantity(
                                hillas_phi_M1[i], unit=u.rad)
                            hillas_parameters_values["length"] = u.Quantity(
                                hillas_length_M1[i], unit=u.mm)
                            hillas_parameters_values["width"] = u.Quantity(
                                hillas_width_M1[i], unit=u.mm)
                            hillas_parameters_values["psi"] = u.Quantity(
                                hillas_psi_M1[i], unit=u.rad)
                            hillas_parameters_values[
                                "skewness"] = hillas_skewness_M1[i]

                            leakage_values[
                                "intensity_width_1"] = leakage_intensity_1_M1[
                                    i]
                            leakage_values[
                                "intensity_width_2"] = leakage_intensity_2_M1[
                                    i]

                            morphology_values["num_pixels"] = 1039
                            morphology_values["num_islands"] = num_islands_M1[
                                i]

                    else:
                        data.dl1.tel[tel_id].image = charge_M2[i][:1039]
                        data.dl1.tel[tel_id].peak_time = peak_time_M2[i][:1039]
                        if self.superstar is not None:
                            data.dl1.tel[tel_id].image_mask = image_mask_M2[
                                i][:1039]

                            hillas_parameters_values[
                                "intensity"] = hillas_intensity_M2[i]
                            hillas_parameters_values["x"] = u.Quantity(
                                hillas_x_M2[i], unit=u.mm)
                            hillas_parameters_values["y"] = u.Quantity(
                                hillas_y_M2[i], unit=u.mm)
                            hillas_parameters_values["r"] = u.Quantity(
                                hillas_r_M2[i], unit=u.mm)
                            hillas_parameters_values["phi"] = u.Quantity(
                                hillas_phi_M2[i], unit=u.rad)
                            hillas_parameters_values["length"] = u.Quantity(
                                hillas_length_M2[i], unit=u.mm)
                            hillas_parameters_values["width"] = u.Quantity(
                                hillas_width_M2[i], unit=u.mm)
                            hillas_parameters_values["psi"] = u.Quantity(
                                hillas_psi_M2[i], unit=u.rad)
                            hillas_parameters_values[
                                "skewness"] = hillas_skewness_M2[i]

                            leakage_values[
                                "intensity_width_1"] = leakage_intensity_1_M2[
                                    i]
                            leakage_values[
                                "intensity_width_2"] = leakage_intensity_2_M2[
                                    i]

                            morphology_values["num_pixels"] = 1039
                            morphology_values["num_islands"] = num_islands_M2[
                                i]

                    if self.superstar is not None:
                        data.dl1.tel[
                            tel_id].parameters.leakage = leakage_values
                        data.dl1.tel[
                            tel_id].parameters.hillas = hillas_parameters_values
                        data.dl1.tel[
                            tel_id].parameters.concentration = concentration_values
                        data.dl1.tel[tel_id].parameters.timing = timing_values
                        data.dl1.tel[
                            tel_id].parameters.morphology = morphology_values

                # Setting the telescopes with data
                data.r0.tels_with_data = tels_with_data
                data.r1.tels_with_data = tels_with_data
                data.dl0.tels_with_data = tels_with_data

                yield data
                counter += 1
        return
Exemplo n.º 24
0
def main():
    std_config = get_standard_config()

    log.setLevel(logging.INFO)
    handler = logging.StreamHandler()
    logging.getLogger().addHandler(handler)

    if args.config_file is not None:
        config = replace_config(std_config, read_configuration_file(args.config_file))
    else:
        config = std_config

    log.info(f"Tailcut config used: {config['tailcut']}")

    foclen = OpticsDescription.from_name('LST').equivalent_focal_length
    cam_table = Table.read(args.input_file, path="instrument/telescope/camera/LSTCam")
    camera_geom = CameraGeometry.from_table(cam_table)

    dl1_container = DL1ParametersContainer()
    parameters_to_update = list(HillasParametersContainer().keys())
    parameters_to_update.extend([
        'concentration_cog',
        'concentration_core',
        'concentration_pixel',
        'leakage_intensity_width_1',
        'leakage_intensity_width_2',
        'leakage_pixels_width_1',
        'leakage_pixels_width_2',
        'n_islands',
        'intercept',
        'time_gradient',
        'n_pixels',
        'wl',
        'log_intensity'
    ])

    nodes_keys = get_dataset_keys(args.input_file)
    if args.noimage:
        nodes_keys.remove(dl1_images_lstcam_key)

    auto_merge_h5files([args.input_file], args.output_file, nodes_keys=nodes_keys)

    with tables.open_file(args.input_file, mode='r') as input:
        image_table = input.root[dl1_images_lstcam_key]
        dl1_params_input = input.root[dl1_params_lstcam_key].colnames
        disp_params = {'disp_dx', 'disp_dy', 'disp_norm', 'disp_angle', 'disp_sign'}
        if set(dl1_params_input).intersection(disp_params):
            parameters_to_update.extend(disp_params)

        with tables.open_file(args.output_file, mode='a') as output:
            params = output.root[dl1_params_lstcam_key].read()
            for ii, row in enumerate(image_table):

                dl1_container.reset()

                image = row['image']
                peak_time = row['peak_time']

                signal_pixels = tailcuts_clean(camera_geom, image, **config['tailcut'])

                n_pixels = np.count_nonzero(signal_pixels)
                if n_pixels > 0:
                    num_islands, island_labels = number_of_islands(camera_geom, signal_pixels)
                    n_pixels_on_island = np.bincount(island_labels.astype(np.int))
                    n_pixels_on_island[0] = 0  # first island is no-island and should not be considered
                    max_island_label = np.argmax(n_pixels_on_island)
                    signal_pixels[island_labels != max_island_label] = False

                    hillas = hillas_parameters(camera_geom[signal_pixels], image[signal_pixels])

                    dl1_container.fill_hillas(hillas)
                    dl1_container.set_timing_features(camera_geom[signal_pixels],
                                                      image[signal_pixels],
                                                      peak_time[signal_pixels],
                                                      hillas)

                    dl1_container.set_leakage(camera_geom, image, signal_pixels)
                    dl1_container.set_concentration(camera_geom, image, hillas)
                    dl1_container.n_islands = num_islands
                    dl1_container.wl = dl1_container.width / dl1_container.length
                    dl1_container.n_pixels = n_pixels
                    width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
                    length = np.rad2deg(np.arctan2(dl1_container.length, foclen))
                    dl1_container.width = width
                    dl1_container.length = length
                    dl1_container.log_intensity = np.log10(dl1_container.intensity)

                if set(dl1_params_input).intersection(disp_params):
                    disp_dx, disp_dy, disp_norm, disp_angle, disp_sign = disp(
                        dl1_container['x'].to_value(u.m),
                        dl1_container['y'].to_value(u.m),
                        params['src_x'][ii],
                        params['src_y'][ii]
                    )

                    dl1_container['disp_dx'] = disp_dx
                    dl1_container['disp_dy'] = disp_dy
                    dl1_container['disp_norm'] = disp_norm
                    dl1_container['disp_angle'] = disp_angle
                    dl1_container['disp_sign'] = disp_sign

                for p in parameters_to_update:
                    params[ii][p] = u.Quantity(dl1_container[p]).value

            output.root[dl1_params_lstcam_key][:] = params
def main():
    std_config = get_standard_config()

    if args.config_file is not None:
        config = replace_config(std_config,
                                read_configuration_file(args.config_file))
    else:
        config = std_config

    print(config['tailcut'])

    foclen = OpticsDescription.from_name('LST').equivalent_focal_length
    cam_table = Table.read(args.input_file,
                           path="instrument/telescope/camera/LSTCam")
    camera_geom = CameraGeometry.from_table(cam_table)

    dl1_container = DL1ParametersContainer()
    parameters_to_update = list(HillasParametersContainer().keys())
    parameters_to_update.extend([
        'concentration_cog',
        'concentration_core',
        'concentration_pixel',
        'leakage_intensity_width_1',
        'leakage_intensity_width_2',
        'leakage_pixels_width_1',
        'leakage_pixels_width_2',
        'n_islands',
        'intercept',
        'time_gradient',
        'n_pixels',
        'wl',
        'r',
    ])

    nodes_keys = get_dataset_keys(args.input_file)
    if args.noimage:
        nodes_keys.remove(dl1_images_lstcam_key)

    auto_merge_h5files([args.input_file],
                       args.output_file,
                       nodes_keys=nodes_keys)

    with tables.open_file(args.input_file, mode='r') as input:
        image_table = input.root[dl1_images_lstcam_key]
        with tables.open_file(args.output_file, mode='a') as output:

            params = output.root[dl1_params_lstcam_key].read()

            for ii, row in enumerate(image_table):
                if ii % 10000 == 0:
                    print(ii)
                image = row['image']
                peak_time = row['peak_time']

                signal_pixels = tailcuts_clean(camera_geom, image,
                                               **config['tailcut'])
                n_pixels = np.count_nonzero(signal_pixels)
                if n_pixels > 0:
                    num_islands, island_labels = number_of_islands(
                        camera_geom, signal_pixels)
                    n_pixels_on_island = np.bincount(
                        island_labels.astype(np.int))
                    n_pixels_on_island[
                        0] = 0  # first island is no-island and should not be considered
                    max_island_label = np.argmax(n_pixels_on_island)
                    signal_pixels[island_labels != max_island_label] = False

                    hillas = hillas_parameters(camera_geom[signal_pixels],
                                               image[signal_pixels])

                    dl1_container.fill_hillas(hillas)
                    dl1_container.set_timing_features(
                        camera_geom[signal_pixels], image[signal_pixels],
                        peak_time[signal_pixels], hillas)

                    dl1_container.set_leakage(camera_geom, image,
                                              signal_pixels)
                    dl1_container.set_concentration(camera_geom, image, hillas)
                    dl1_container.n_islands = num_islands
                    dl1_container.wl = dl1_container.width / dl1_container.length
                    dl1_container.n_pixels = n_pixels
                    width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
                    length = np.rad2deg(
                        np.arctan2(dl1_container.length, foclen))
                    dl1_container.width = width
                    dl1_container.length = length
                    dl1_container.r = np.sqrt(dl1_container.x**2 +
                                              dl1_container.y**2)

                else:
                    # for consistency with r0_to_dl1.py:
                    for key in dl1_container.keys():
                        dl1_container[key] = \
                            u.Quantity(0, dl1_container.fields[key].unit)

                    dl1_container.width = u.Quantity(np.nan, u.m)
                    dl1_container.length = u.Quantity(np.nan, u.m)
                    dl1_container.wl = u.Quantity(np.nan, u.m)

            for p in parameters_to_update:
                params[ii][p] = u.Quantity(dl1_container[p]).value

            output.root[dl1_params_lstcam_key][:] = params
Exemplo n.º 26
0
def test_array_display():
    """ check that we can do basic array display functionality """
    from ctapipe.visualization.mpl_array import ArrayDisplay
    from ctapipe.image import timing_parameters

    from ctapipe.containers import (
        ArrayEventContainer,
        DL1Container,
        DL1CameraContainer,
        ImageParametersContainer,
        CoreParametersContainer,
    )

    # build a test subarray:
    tels = dict()
    tel_pos = dict()
    for ii, pos in enumerate([[0, 0, 0], [100, 0, 0], [-100, 0, 0]] * u.m):
        tels[ii + 1] = TelescopeDescription.from_name("MST", "NectarCam")
        tel_pos[ii + 1] = pos

    sub = SubarrayDescription(name="TestSubarray",
                              tel_positions=tel_pos,
                              tel_descriptions=tels)

    # Create a fake event containing telescope-wise information about
    # the image directions projected on the ground
    event = ArrayEventContainer()
    event.dl1 = DL1Container()
    event.dl1.tel = {1: DL1CameraContainer(), 2: DL1CameraContainer()}
    event.dl1.tel[1].parameters = ImageParametersContainer()
    event.dl1.tel[2].parameters = ImageParametersContainer()
    event.dl1.tel[2].parameters.core = CoreParametersContainer()
    event.dl1.tel[1].parameters.core = CoreParametersContainer()
    event.dl1.tel[1].parameters.core.psi = u.Quantity(2.0, unit=u.deg)
    event.dl1.tel[2].parameters.core.psi = u.Quantity(1.0, unit=u.deg)

    ad = ArrayDisplay(subarray=sub)
    ad.set_vector_rho_phi(1 * u.m, 90 * u.deg)

    # try setting a value
    vals = np.ones(sub.num_tels)
    ad.values = vals

    assert (vals == ad.values).all()

    # test UV field ...

    # ...with colors by telescope type
    ad.set_vector_uv(np.array([1, 2, 3]) * u.m, np.array([1, 2, 3]) * u.m)
    # ...with scalar color
    ad.set_vector_uv(np.array([1, 2, 3]) * u.m, np.array([1, 2, 3]) * u.m, c=3)

    geom = CameraGeometry.from_name("LSTCam")
    rot_angle = 20 * u.deg
    hillas = CameraHillasParametersContainer(x=0 * u.m,
                                             y=0 * u.m,
                                             psi=rot_angle)

    # test using hillas params CameraFrame:
    hillas_dict = {
        1: CameraHillasParametersContainer(length=100.0 * u.m, psi=90 * u.deg),
        2: CameraHillasParametersContainer(length=20000 * u.cm, psi="95deg"),
    }

    grad = 2
    intercept = 1

    timing_rot20 = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peak_time=intercept + grad * geom.pix_x.value,
        hillas_parameters=hillas,
        cleaning_mask=np.ones(geom.n_pixels, dtype=bool),
    )
    gradient_dict = {1: timing_rot20.slope.value, 2: timing_rot20.slope.value}
    core_dict = {
        tel_id: dl1.parameters.core.psi
        for tel_id, dl1 in event.dl1.tel.items()
    }
    ad.set_vector_hillas(
        hillas_dict=hillas_dict,
        core_dict=core_dict,
        length=500,
        time_gradient=gradient_dict,
        angle_offset=0 * u.deg,
    )
    ad.set_line_hillas(hillas_dict=hillas_dict, core_dict=core_dict, range=300)

    # test using hillas params for divergent pointing in telescopeframe:
    hillas_dict = {
        1:
        HillasParametersContainer(fov_lon=1.0 * u.deg,
                                  fov_lat=1.0 * u.deg,
                                  length=1.0 * u.deg,
                                  psi=90 * u.deg),
        2:
        HillasParametersContainer(fov_lon=1.0 * u.deg,
                                  fov_lat=1.0 * u.deg,
                                  length=1.0 * u.deg,
                                  psi=95 * u.deg),
    }
    ad.set_vector_hillas(
        hillas_dict=hillas_dict,
        core_dict=core_dict,
        length=500,
        time_gradient=gradient_dict,
        angle_offset=0 * u.deg,
    )
    ad.set_line_hillas(hillas_dict=hillas_dict, core_dict=core_dict, range=300)

    # test using hillas params for parallel pointing in telescopeframe:
    hillas_dict = {
        1:
        HillasParametersContainer(fov_lon=1.0 * u.deg,
                                  fov_lat=1.0 * u.deg,
                                  length=1.0 * u.deg,
                                  psi=90 * u.deg),
        2:
        HillasParametersContainer(fov_lon=1.0 * u.deg,
                                  fov_lat=1.0 * u.deg,
                                  length=1.0 * u.deg,
                                  psi=95 * u.deg),
    }
    ad.set_vector_hillas(
        hillas_dict=hillas_dict,
        core_dict=core_dict,
        length=500,
        time_gradient=gradient_dict,
        angle_offset=0 * u.deg,
    )

    # test negative time_gradients
    gradient_dict = {1: -0.03, 2: -0.02}
    ad.set_vector_hillas(
        hillas_dict=hillas_dict,
        core_dict=core_dict,
        length=500,
        time_gradient=gradient_dict,
        angle_offset=0 * u.deg,
    )
    # and very small
    gradient_dict = {1: 0.003, 2: 0.002}
    ad.set_vector_hillas(
        hillas_dict=hillas_dict,
        core_dict=core_dict,
        length=500,
        time_gradient=gradient_dict,
        angle_offset=0 * u.deg,
    )

    # Test background contour
    ad.background_contour(
        x=np.array([0, 1, 2]),
        y=np.array([0, 1, 2]),
        background=np.array([[0, 1, 2], [0, 1, 2], [0, 1, 2]]),
    )

    ad.set_line_hillas(hillas_dict=hillas_dict, core_dict=core_dict, range=300)
    ad.add_labels()
    ad.remove_labels()
    def _generator(self):
        """
        Stereo event generator. Yields DataContainer instances, filled
        with the read event data.

        Returns
        -------

        """
        counter = 0
        data = DataContainer()
        data.meta["origin"] = "MAGIC"
        data.meta["input_url"] = self.input_url
        data.meta["is_simulation"] = self.mc
        data.mcheader = self._header

        if self.calib_M1 is not None and self.calib_M2 is not None:
            # Reading data from root file for Events table
            shower_primary_id = self.magic_to_cta_shower_primary_id[int(
                self.superstar["MMcEvt_1.fPartId"].array()[0])]
            eventid_M1 = np.asarray(
                self.calib_M1["MRawEvtHeader.fStereoEvtNumber"].array())
            eventid_M2 = np.asarray(
                self.calib_M2["MRawEvtHeader.fStereoEvtNumber"].array())
            zenith = np.asarray(self.calib_M1["MMcEvt.fTheta"].array())
            pointing_altitude = np.asarray(
                self.calib_M1["MPointingPos.fZd"].array())
            azimuth = np.asarray(self.calib_M1["MMcEvt.fPhi"].array())
            pointing_azimuth = np.asarray(
                self.calib_M1["MPointingPos.fAz"].array())
            core_x = np.asarray(self.calib_M1["MMcEvt.fCoreX"].array())
            core_y = np.asarray(self.calib_M1["MMcEvt.fCoreY"].array())
            mc_energy = np.asarray(
                self.calib_M1["MMcEvt.fEnergy"].array()) / 1000.0
            h_first_int = np.asarray(
                self.calib_M1["MMcEvt.fZFirstInteraction"].array())

            # Reading data from root file for Image table
            charge_M1 = np.asarray(
                self.calib_M1["MCerPhotEvt.fPixels.fPhot"].array())
            peak_time_M1 = np.asarray(
                self.calib_M1["MArrivalTime.fData"].array())
            image_mask_M1 = np.asarray(self.calib_M1["CleanCharge"].array())
            for i, mask in enumerate(image_mask_M1):
                image_mask_M1[i] = np.array(mask) != 0

            charge_M2 = np.asarray(
                self.calib_M2["MCerPhotEvt.fPixels.fPhot"].array())
            peak_time_M2 = np.asarray(
                self.calib_M2["MArrivalTime.fData"].array())
            image_mask_M2 = np.asarray(self.calib_M2["CleanCharge"].array())
            for i, mask in enumerate(image_mask_M2):
                image_mask_M2[i] = np.array(mask) != 0

        if self.superstar is not None:
            # Reading data from root file for Events table
            # only read MC information if it exists
            if self.is_simulation:
                shower_primary_id = self.magic_to_cta_shower_primary_id[int(
                    self.superstar["MMcEvt_1.fPartId"].array()[0])]
                src_pos_cam_Y = np.asarray(
                    self.superstar["MSrcPosCam_1.fY"].array())
                src_pos_cam_X = np.asarray(
                    self.superstar["MSrcPosCam_1.fX"].array())
                core_x = np.asarray(self.superstar["MMcEvt_1.fCoreX"].array())
                core_y = np.asarray(self.superstar["MMcEvt_1.fCoreY"].array())
                mc_energy = (
                    np.asarray(self.superstar["MMcEvt_1.fEnergy"].array()) /
                    1000.0)
                h_first_int = np.asarray(
                    self.superstar["MMcEvt_1.fZFirstInteraction"].array())

            eventid_M1 = np.asarray(
                self.superstar["MRawEvtHeader_1.fStereoEvtNumber"].array())
            eventid_M2 = np.asarray(
                self.superstar["MRawEvtHeader_2.fStereoEvtNumber"].array())
            pointing_altitude = np.asarray(
                self.superstar["MPointingPos_1.fZd"].array())
            pointing_azimuth = np.asarray(
                self.superstar["MPointingPos_1.fAz"].array())

            # Reading data from root file for Parameter table
            hillas_intensity_M1 = np.asarray(
                self.superstar["MHillas_1.fSize"].array())
            hillas_intensity_M2 = np.asarray(
                self.superstar["MHillas_2.fSize"].array())
            hillas_x_M1 = np.asarray(
                self.superstar["MHillas_1.fMeanX"].array())
            hillas_x_M2 = np.asarray(
                self.superstar["MHillas_2.fMeanX"].array())
            hillas_y_M1 = np.asarray(
                self.superstar["MHillas_1.fMeanY"].array())
            hillas_y_M2 = np.asarray(
                self.superstar["MHillas_2.fMeanY"].array())
            hillas_r_M1 = np.sqrt(
                np.power(hillas_x_M1, 2) + np.power(hillas_y_M1, 2))
            hillas_r_M2 = np.sqrt(
                np.power(hillas_x_M2, 2) + np.power(hillas_y_M2, 2))
            hillas_phi_M1 = np.arctan2(hillas_y_M1, hillas_x_M1)
            hillas_phi_M2 = np.arctan2(hillas_y_M2, hillas_x_M2)
            hillas_length_M1 = np.asarray(
                self.superstar["MHillas_1.fLength"].array())
            hillas_length_M2 = np.asarray(
                self.superstar["MHillas_2.fLength"].array())
            hillas_width_M1 = np.asarray(
                self.superstar["MHillas_1.fWidth"].array())
            hillas_width_M2 = np.asarray(
                self.superstar["MHillas_2.fWidth"].array())
            hillas_psi_M1 = np.asarray(
                self.superstar["MHillas_1.fDelta"].array())
            hillas_psi_M2 = np.asarray(
                self.superstar["MHillas_2.fDelta"].array())
            hillas_skewness_M1 = np.asarray(
                self.superstar["MHillasExt_1.fM3Long"].array())
            hillas_skewness_M2 = np.asarray(
                self.superstar["MHillasExt_2.fM3Long"].array())

            leakage_intensity_1_M1 = np.asarray(
                self.superstar["MNewImagePar_1.fLeakage1"].array())
            leakage_intensity_1_M2 = np.asarray(
                self.superstar["MNewImagePar_2.fLeakage1"].array())
            leakage_intensity_2_M1 = np.asarray(
                self.superstar["MNewImagePar_1.fLeakage2"].array())
            leakage_intensity_2_M2 = np.asarray(
                self.superstar["MNewImagePar_2.fLeakage2"].array())

            num_islands_M1 = np.asarray(
                self.superstar["MImagePar_1.fNumIslands"].array())
            num_islands_M2 = np.asarray(
                self.superstar["MImagePar_2.fNumIslands"].array())
            x_max = np.asarray(self.superstar["MStereoPar.fXMax"].array())

            # Reading data from root file for Image table (charge, peak time and image mask)
            charge_M1 = np.asarray(self.superstar["UprootImageOrig_1"].array())
            for i, charge in enumerate(charge_M1):
                charge_M1[i] = np.array(charge)
            peak_time_M1 = np.asarray(
                self.superstar["MArrivalTime_1.fData"].array())
            image_mask_M1 = np.asarray(
                self.superstar["UprootImageOrigClean_1"].array())
            for i, mask in enumerate(image_mask_M1):
                image_mask_M1[i] = np.array(mask) != 0

            charge_M2 = np.asarray(self.superstar["UprootImageOrig_2"].array())
            for i, charge in enumerate(charge_M2):
                charge_M2[i] = np.array(charge)

            charge_M2 = np.asarray(
                self.superstar["MCerPhotEvt_2.fPixels.fPhot"].array())
            peak_time_M2 = np.asarray(
                self.superstar["MArrivalTime_2.fData"].array())
            image_mask_M2 = np.asarray(
                self.superstar["UprootImageOrigClean_2"].array())
            for i, mask in enumerate(image_mask_M2):
                image_mask_M2[i] = np.array(mask) != 0

        # Iterating over all events, and saving only stereo ones
        total_events = min(len(charge_M1), len(charge_M2))
        tels_with_data = {1, 2}
        for i in range(0, total_events):
            if eventid_M1[i] != 0:
                obs_id = self.run_number
                event_id = eventid_M1[i]
                i2 = np.where(eventid_M2 == eventid_M1[i])
                i2 = i2[0].astype(int)
                data.count = counter

                # Setting up the Data container
                data.index.obs_id = obs_id
                data.index.event_id = event_id
                data.r0.tel.clear()
                data.r1.tel.clear()
                data.dl0.tel.clear()

                # Adding the array pointing in the pointing container
                data.pointing.array_altitude = u.Quantity(
                    np.deg2rad(90.0 - pointing_altitude[i]), u.rad)
                data.pointing.array_azimuth = u.Quantity(
                    np.deg2rad(pointing_azimuth[i]), u.rad)

                # Filling the DL1 container with the event data
                for tel_id in tels_with_data:
                    # Adding telescope pointing container
                    data.pointing.tel[tel_id].azimuth = u.Quantity(
                        np.deg2rad(pointing_azimuth[i]), u.rad)
                    data.pointing.tel[tel_id].altitude = u.Quantity(
                        np.deg2rad(90.0 - pointing_altitude[i]), u.rad)

                    # Adding MC data
                    if self.is_simulation:
                        data.mc.alt = Angle(
                            np.deg2rad(src_pos_cam_Y[i] * 0.00337), u.rad)
                        data.mc.az = Angle(
                            np.deg2rad(src_pos_cam_X[i] * 0.00337), u.rad)
                        data.mc.x_max = u.Quantity(x_max[i], X_MAX_UNIT)
                        data.mc.h_first_int = u.Quantity(h_first_int[i], u.m)
                        data.mc.core_x = u.Quantity(core_x[i], u.m)
                        data.mc.core_y = u.Quantity(core_y[i], u.m)
                        data.mc.energy = u.Quantity(mc_energy[i], u.TeV)
                        data.mc.shower_primary_id = shower_primary_id

                    if self.superstar is not None:
                        leakage_values = LeakageContainer()
                        hillas_parameters_values = HillasParametersContainer()
                        concentration_values = ConcentrationContainer()
                        timing_values = TimingParametersContainer()
                        morphology_values = MorphologyContainer()

                    # Adding charge, peak time and parameters
                    if tel_id == 1:
                        data.dl1.tel[tel_id].image = charge_M1[i][:1039]
                        data.dl1.tel[tel_id].peak_time = peak_time_M1[i][:1039]
                        data.dl1.tel[tel_id].image_mask = image_mask_M1[
                            i][:1039]

                        if self.superstar is not None:
                            hillas_parameters_values[
                                "intensity"] = hillas_intensity_M1[i]
                            hillas_parameters_values["x"] = u.Quantity(
                                hillas_x_M1[i], unit=u.mm)
                            hillas_parameters_values["y"] = u.Quantity(
                                hillas_y_M1[i], unit=u.mm)
                            hillas_parameters_values["r"] = u.Quantity(
                                hillas_r_M1[i], unit=u.mm)
                            hillas_parameters_values["phi"] = u.Quantity(
                                hillas_phi_M1[i], unit=u.rad)
                            hillas_parameters_values["length"] = u.Quantity(
                                hillas_length_M1[i], unit=u.mm)
                            hillas_parameters_values["width"] = u.Quantity(
                                hillas_width_M1[i], unit=u.mm)
                            hillas_parameters_values["psi"] = u.Quantity(
                                hillas_psi_M1[i], unit=u.rad)
                            hillas_parameters_values[
                                "skewness"] = hillas_skewness_M1[i]

                            leakage_values[
                                "intensity_width_1"] = leakage_intensity_1_M1[
                                    i]
                            leakage_values[
                                "intensity_width_2"] = leakage_intensity_2_M1[
                                    i]

                            morphology_values["num_islands"] = num_islands_M1[
                                i]

                    else:
                        data.dl1.tel[tel_id].image = charge_M2[i][:1039]
                        data.dl1.tel[tel_id].peak_time = peak_time_M2[i][:1039]
                        data.dl1.tel[tel_id].image_mask = image_mask_M2[
                            i][:1039]

                        if self.superstar is not None:
                            hillas_parameters_values[
                                "intensity"] = hillas_intensity_M2[i]
                            hillas_parameters_values["x"] = u.Quantity(
                                hillas_x_M2[i], unit=u.mm)
                            hillas_parameters_values["y"] = u.Quantity(
                                hillas_y_M2[i], unit=u.mm)
                            hillas_parameters_values["r"] = u.Quantity(
                                hillas_r_M2[i], unit=u.mm)
                            hillas_parameters_values["phi"] = u.Quantity(
                                hillas_phi_M2[i], unit=u.rad)
                            hillas_parameters_values["length"] = u.Quantity(
                                hillas_length_M2[i], unit=u.mm)
                            hillas_parameters_values["width"] = u.Quantity(
                                hillas_width_M2[i], unit=u.mm)
                            hillas_parameters_values["psi"] = u.Quantity(
                                hillas_psi_M2[i], unit=u.rad)
                            hillas_parameters_values[
                                "skewness"] = hillas_skewness_M2[i]

                            leakage_values[
                                "intensity_width_1"] = leakage_intensity_1_M2[
                                    i]
                            leakage_values[
                                "intensity_width_2"] = leakage_intensity_2_M2[
                                    i]

                            morphology_values["num_islands"] = num_islands_M2[
                                i]

                    if self.superstar is not None:
                        data.dl1.tel[
                            tel_id].parameters.leakage = leakage_values
                        data.dl1.tel[
                            tel_id].parameters.hillas = hillas_parameters_values
                        data.dl1.tel[
                            tel_id].parameters.concentration = concentration_values
                        data.dl1.tel[tel_id].parameters.timing = timing_values
                        data.dl1.tel[
                            tel_id].parameters.morphology = morphology_values

                # Setting the telescopes with data
                data.r0.tels_with_data = tels_with_data
                data.r1.tels_with_data = tels_with_data
                data.dl0.tels_with_data = tels_with_data

                yield data
                counter += 1
        return
Exemplo n.º 28
0
    def _generate_events(self):
        """
        Yield ArrayEventContainer to iterate through events.
        """
        data = ArrayEventContainer()
        # Maybe take some other metadata, but there are still some 'unknown'
        # written out by the stage1 tool
        data.meta["origin"] = self.file_.root._v_attrs["CTA PROCESS TYPE"]
        data.meta["input_url"] = self.input_url
        data.meta["max_events"] = self.max_events

        if DataLevel.DL1_IMAGES in self.datalevels:
            image_iterators = {
                tel.name: self.file_.root.dl1.event.telescope.images[
                    tel.name
                ].iterrows()
                for tel in self.file_.root.dl1.event.telescope.images
            }
            if self.has_simulated_dl1:
                simulated_image_iterators = {
                    tel.name: self.file_.root.simulation.event.telescope.images[
                        tel.name
                    ].iterrows()
                    for tel in self.file_.root.simulation.event.telescope.images
                }

        if DataLevel.DL1_PARAMETERS in self.datalevels:
            param_readers = {
                tel.name: HDF5TableReader(self.file_).read(
                    f"/dl1/event/telescope/parameters/{tel.name}",
                    containers=[
                        HillasParametersContainer(),
                        TimingParametersContainer(),
                        LeakageContainer(),
                        ConcentrationContainer(),
                        MorphologyContainer(),
                        IntensityStatisticsContainer(),
                        PeakTimeStatisticsContainer(),
                    ],
                    prefixes=True,
                )
                for tel in self.file_.root.dl1.event.telescope.parameters
            }
            if self.has_simulated_dl1:
                simulated_param_readers = {
                    tel.name: HDF5TableReader(self.file_).read(
                        f"/simulation/event/telescope/parameters/{tel.name}",
                        containers=[
                            HillasParametersContainer(),
                            LeakageContainer(),
                            ConcentrationContainer(),
                            MorphologyContainer(),
                            IntensityStatisticsContainer(),
                        ],
                        prefixes=True,
                    )
                    for tel in self.file_.root.dl1.event.telescope.parameters
                }

        if self.is_simulation:
            # simulated shower wide information
            mc_shower_reader = HDF5TableReader(self.file_).read(
                "/simulation/event/subarray/shower",
                SimulatedShowerContainer(),
                prefixes="true",
            )

        # Setup iterators for the array events
        events = HDF5TableReader(self.file_).read(
            "/dl1/event/subarray/trigger", [TriggerContainer(), EventIndexContainer()]
        )

        array_pointing_finder = IndexFinder(
            self.file_.root.dl1.monitoring.subarray.pointing.col("time")
        )

        tel_pointing_finder = {
            tel.name: IndexFinder(tel.col("time"))
            for tel in self.file_.root.dl1.monitoring.telescope.pointing
        }

        for counter, array_event in enumerate(events):
            data.dl1.tel.clear()
            data.simulation.tel.clear()
            data.pointing.tel.clear()
            data.trigger.tel.clear()

            data.count = counter
            data.trigger, data.index = next(events)
            data.trigger.tels_with_trigger = (
                np.where(data.trigger.tels_with_trigger)[0] + 1
            )  # +1 to match array index to telescope id

            # Maybe there is a simpler way  to do this
            # Beware: tels_with_trigger contains all triggered telescopes whereas
            # the telescope trigger table contains only the subset of
            # allowed_tels given during the creation of the dl1 file
            for i in self.file_.root.dl1.event.telescope.trigger.where(
                f"(obs_id=={data.index.obs_id}) & (event_id=={data.index.event_id})"
            ):
                if self.allowed_tels and i["tel_id"] not in self.allowed_tels:
                    continue
                if self.datamodel_version == "v1.0.0":
                    data.trigger.tel[i["tel_id"]].time = i["telescopetrigger_time"]
                else:
                    data.trigger.tel[i["tel_id"]].time = i["time"]

            self._fill_array_pointing(data, array_pointing_finder)
            self._fill_telescope_pointing(data, tel_pointing_finder)

            if self.is_simulation:
                data.simulation.shower = next(mc_shower_reader)

            for tel in data.trigger.tel.keys():
                if self.allowed_tels and tel not in self.allowed_tels:
                    continue
                if self.has_simulated_dl1:
                    simulated = data.simulation.tel[tel]
                dl1 = data.dl1.tel[tel]
                if DataLevel.DL1_IMAGES in self.datalevels:
                    if f"tel_{tel:03d}" not in image_iterators.keys():
                        logger.debug(
                            f"Triggered telescope {tel} is missing "
                            "from the image table."
                        )
                        continue
                    image_row = next(image_iterators[f"tel_{tel:03d}"])
                    dl1.image = image_row["image"]
                    dl1.peak_time = image_row["peak_time"]
                    dl1.image_mask = image_row["image_mask"]

                    if self.has_simulated_dl1:
                        if f"tel_{tel:03d}" not in simulated_image_iterators.keys():
                            logger.warning(
                                f"Triggered telescope {tel} is missing "
                                "from the simulated image table, but was present at the "
                                "reconstructed image table."
                            )
                            continue
                        simulated_image_row = next(
                            simulated_image_iterators[f"tel_{tel:03d}"]
                        )
                        simulated.true_image = simulated_image_row["true_image"]

                if DataLevel.DL1_PARAMETERS in self.datalevels:
                    if f"tel_{tel:03d}" not in param_readers.keys():
                        logger.debug(
                            f"Triggered telescope {tel} is missing "
                            "from the parameters table."
                        )
                        continue
                    # Is there a smarter way to unpack this?
                    # Best would probbaly be if we could directly read
                    # into the ImageParametersContainer
                    params = next(param_readers[f"tel_{tel:03d}"])
                    dl1.parameters.hillas = params[0]
                    dl1.parameters.timing = params[1]
                    dl1.parameters.leakage = params[2]
                    dl1.parameters.concentration = params[3]
                    dl1.parameters.morphology = params[4]
                    dl1.parameters.intensity_statistics = params[5]
                    dl1.parameters.peak_time_statistics = params[6]

                    if self.has_simulated_dl1:
                        if f"tel_{tel:03d}" not in param_readers.keys():
                            logger.debug(
                                f"Triggered telescope {tel} is missing "
                                "from the simulated parameters table, but was "
                                "present at the reconstructed parameters table."
                            )
                            continue
                        simulated_params = next(
                            simulated_param_readers[f"tel_{tel:03d}"]
                        )
                        simulated.true_parameters.hillas = simulated_params[0]
                        simulated.true_parameters.leakage = simulated_params[1]
                        simulated.true_parameters.concentration = simulated_params[2]
                        simulated.true_parameters.morphology = simulated_params[3]
                        simulated.true_parameters.intensity_statistics = simulated_params[
                            4
                        ]

            yield data
Exemplo n.º 29
0
    def predict(self, hillas_dict, subarray, array_pointing, telescopes_pointings=None):
        """

        Parameters
        ----------
        hillas_dict: dict
            Dictionary containing Hillas parameters for all telescopes
            in reconstruction
        inst : ctapipe.io.InstrumentContainer
            instrumental description
        array_pointing: SkyCoord[AltAz]
            pointing direction of the array
        telescopes_pointings: dict[SkyCoord[AltAz]]
            dictionary of pointing direction per each telescope

        Returns
        -------
        ReconstructedShowerContainer:

        """

        # filter warnings for missing obs time. this is needed because MC data has no obs time
        warnings.filterwarnings(action="ignore", category=MissingFrameAttributeWarning)

        # stereoscopy needs at least two telescopes
        if len(hillas_dict) < 2:
            raise TooFewTelescopesException(
                "need at least two telescopes, have {}".format(len(hillas_dict))
            )

        # check for np.nan or 0 width's as these screw up weights
        if any([np.isnan(hillas_dict[tel]["width"].value) for tel in hillas_dict]):
            raise InvalidWidthException(
                "A HillasContainer contains an ellipse of width==np.nan"
            )

        if any([hillas_dict[tel]["width"].value == 0 for tel in hillas_dict]):
            raise InvalidWidthException(
                "A HillasContainer contains an ellipse of width==0"
            )

        if telescopes_pointings is None:
            telescopes_pointings = {
                tel_id: array_pointing for tel_id in hillas_dict.keys()
            }

        tilted_frame = TiltedGroundFrame(pointing_direction=array_pointing)
        grd_coord = subarray.tel_coords
        tilt_coord = grd_coord.transform_to(tilted_frame)

        tel_ids = list(hillas_dict.keys())
        tel_indices = subarray.tel_ids_to_indices(tel_ids)

        tel_x = {
            tel_id: tilt_coord.x[tel_index]
            for tel_id, tel_index in zip(tel_ids, tel_indices)
        }
        tel_y = {
            tel_id: tilt_coord.y[tel_index]
            for tel_id, tel_index in zip(tel_ids, tel_indices)
        }

        nom_frame = NominalFrame(origin=array_pointing)

        hillas_dict_mod = {}

        for tel_id, hillas in hillas_dict.items():
            if isinstance(hillas, CameraHillasParametersContainer):
                focal_length = subarray.tel[tel_id].optics.equivalent_focal_length
                camera_frame = CameraFrame(
                    telescope_pointing=telescopes_pointings[tel_id],
                    focal_length=focal_length,
                )
                cog_coords = SkyCoord(x=hillas.x, y=hillas.y, frame=camera_frame)
                cog_coords_nom = cog_coords.transform_to(nom_frame)
            else:
                telescope_frame = TelescopeFrame(
                    telescope_pointing=telescopes_pointings[tel_id]
                )
                cog_coords = SkyCoord(
                    fov_lon=hillas.fov_lon,
                    fov_lat=hillas.fov_lat,
                    frame=telescope_frame,
                )
                cog_coords_nom = cog_coords.transform_to(nom_frame)
            hillas_dict_mod[tel_id] = HillasParametersContainer(
                fov_lon=cog_coords_nom.fov_lon,
                fov_lat=cog_coords_nom.fov_lat,
                psi=hillas.psi,
                width=hillas.width,
                length=hillas.length,
                intensity=hillas.intensity,
            )

        src_fov_lon, src_fov_lat, err_fov_lon, err_fov_lat = self.reconstruct_nominal(
            hillas_dict_mod
        )
        core_x, core_y, core_err_x, core_err_y = self.reconstruct_tilted(
            hillas_dict_mod, tel_x, tel_y
        )

        err_fov_lon *= u.rad
        err_fov_lat *= u.rad

        nom = SkyCoord(
            fov_lon=src_fov_lon * u.rad, fov_lat=src_fov_lat * u.rad, frame=nom_frame
        )
        sky_pos = nom.transform_to(array_pointing.frame)
        tilt = SkyCoord(x=core_x * u.m, y=core_y * u.m, frame=tilted_frame)
        grd = project_to_ground(tilt)
        x_max = self.reconstruct_xmax(
            nom.fov_lon,
            nom.fov_lat,
            tilt.x,
            tilt.y,
            hillas_dict_mod,
            tel_x,
            tel_y,
            90 * u.deg - array_pointing.alt,
        )

        src_error = np.sqrt(err_fov_lon ** 2 + err_fov_lat ** 2)

        result = ReconstructedGeometryContainer(
            alt=sky_pos.altaz.alt.to(u.rad),
            az=sky_pos.altaz.az.to(u.rad),
            core_x=grd.x,
            core_y=grd.y,
            core_uncert=u.Quantity(np.sqrt(core_err_x ** 2 + core_err_y ** 2), u.m),
            tel_ids=[h for h in hillas_dict_mod.keys()],
            average_intensity=np.mean([h.intensity for h in hillas_dict_mod.values()]),
            is_valid=True,
            alt_uncert=src_error.to(u.rad),
            az_uncert=src_error.to(u.rad),
            h_max=x_max,
            h_max_uncert=u.Quantity(np.nan * x_max.unit),
            goodness_of_fit=np.nan,
        )
        return result
Exemplo n.º 30
0
def test_reconstructors(reconstructors):
    """
    a test of the complete fit procedure on one event including:
    • tailcut cleaning
    • hillas parametrisation
    • HillasPlane creation
    • direction fit
    • position fit

    in the end, proper units in the output are asserted"""

    filename = get_dataset_path(
        "gamma_LaPalma_baseline_20Zd_180Az_prod3b_test.simtel.gz")

    source = EventSource(filename, max_events=10)
    subarray = source.subarray
    calib = CameraCalibrator(source.subarray)
    horizon_frame = AltAz()

    for event in source:
        calib(event)
        sim_shower = event.simulation.shower
        array_pointing = SkyCoord(az=sim_shower.az,
                                  alt=sim_shower.alt,
                                  frame=horizon_frame)

        telescope_pointings = {}

        for tel_id, dl1 in event.dl1.tel.items():

            geom = source.subarray.tel[tel_id].camera.geometry

            telescope_pointings[tel_id] = SkyCoord(
                alt=event.pointing.tel[tel_id].altitude,
                az=event.pointing.tel[tel_id].azimuth,
                frame=horizon_frame,
            )
            mask = tailcuts_clean(geom,
                                  dl1.image,
                                  picture_thresh=10.0,
                                  boundary_thresh=5.0)

            dl1.parameters = ImageParametersContainer()

            try:
                moments = hillas_parameters(geom[mask], dl1.image[mask])
            except HillasParameterizationError:
                dl1.parameters.hillas = HillasParametersContainer()
                continue

            # Make sure we provide only good images for the test
            if np.isnan(moments.width.value) or (moments.width.value == 0):
                dl1.parameters.hillas = HillasParametersContainer()
            else:
                dl1.parameters.hillas = moments

        hillas_dict = {
            tel_id: dl1.parameters.hillas
            for tel_id, dl1 in event.dl1.tel.items()
            if np.isfinite(dl1.parameters.hillas.intensity)
        }
        if len(hillas_dict) < 2:
            continue

        for count, reco_method in enumerate(reconstructors):
            if reco_method is HillasReconstructor:
                reconstructor = HillasReconstructor(subarray)

                reconstructor(event)

                event.dl2.stereo.geometry["HillasReconstructor"].alt.to(u.deg)
                event.dl2.stereo.geometry["HillasReconstructor"].az.to(u.deg)
                event.dl2.stereo.geometry["HillasReconstructor"].core_x.to(u.m)
                assert event.dl2.stereo.geometry[
                    "HillasReconstructor"].is_valid

            else:
                reconstructor = reco_method()

                try:
                    reconstructor_out = reconstructor.predict(
                        hillas_dict,
                        source.subarray,
                        array_pointing,
                        telescope_pointings,
                    )
                except InvalidWidthException:
                    continue

                reconstructor_out.alt.to(u.deg)
                reconstructor_out.az.to(u.deg)
                reconstructor_out.core_x.to(u.m)
                assert reconstructor_out.is_valid