Exemple #1
0
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)
Exemple #2
0
def test_array_display():
    from ctapipe.visualization.mpl_array import ArrayDisplay

    # 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=1.0 * u.m, phi=90 * u.deg),
        2: HillasParametersContainer(length=200 * u.cm, phi="95deg"),
    }
    ad.set_vector_hillas(hillas_dict)

    ad.add_labels()
    ad.remove_labels()
Exemple #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)
Exemple #4
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)
Exemple #5
0
def test_array_display():
    """ check that we can do basic array display functionality """
    from ctapipe.visualization.mpl_array import ArrayDisplay
    from ctapipe.image.timing_parameters 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),
        pulse_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()
Exemple #6
0
def test_array_display():
    from ctapipe.visualization.mpl_array import ArrayDisplay
    from ctapipe.image.timing_parameters 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

    rot_angle = 20 * u.deg
    timing_rot20 = timing_parameters(pix_x=arange(4) * u.deg,
                                     pix_y=zeros(4) * u.deg,
                                     image=ones(4),
                                     peak_time=intercept * u.ns +
                                     grad * arange(4) * u.ns,
                                     rotation_angle=rot_angle)
    gradient_dict = {
        1: timing_rot20.gradient.value,
        2: timing_rot20.gradient.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()
Exemple #7
0
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.delta_az,
                                        source_y=nom_pos_reco.delta_alt,
                                        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)
class TelescopeParameterContainer(Container):

    container_prefix = ''

    telescope_id = Field(-1, 'telescope id')
    run_id = Field(-1, 'run id')
    array_event_id = Field(-1, 'array event id')

    leakage = Field(LeakageContainer(), 'Leakage container')
    hillas = Field(HillasParametersContainer(), 'HillasParametersContainer')
    concentration = Field(ConcentrationContainer(), 'ConcentrationContainer')
    timing = Field(TimingParametersContainer(), 'TimingParametersContainer')
    islands = Field(IslandContainer(), 'IslandContainer')
    num_pixel_in_shower = Field(np.nan, 'number of pixels after cleaning')

    pointing = Field(TelescopePointingContainer(), 'pointing information')

    distance_to_reconstructed_core_position = Field(
        np.nan,
        'Distance from telescope to reconstructed impact position',
        unit=u.m)

    camera_type_id = Field(
        np.nan,
        'An ID encoding the camera type (SCT, ASTRI, CHEC, ...)')
    telescope_type_id = Field(
        np.nan,
        'An ID encoding the telescope type (MST, SST, LST)')

    mirror_area = Field(np.nan, 'Mirror Area', unit=u.m**2)
    focal_length = Field(np.nan, 'focal length', unit=u.m)
def test_psi_0():
    """
    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)
    pulse_time = intercept + grad * geom.pix_x.value
    pulse_time += random.normal(0, deviation, geom.n_pixels)

    timing = timing_parameters(geom,
                               image=np.ones(geom.n_pixels),
                               pulse_time=pulse_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)
def test_ignore_negative():
    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)
    pulse_time = intercept + grad * geom.pix_x.value
    pulse_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,
        pulse_time=pulse_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)
def test_psi_20():

    # 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)
    pulse_time = intercept + grad * (np.cos(psi) * geom.pix_x.value +
                                     np.sin(psi) * geom.pix_y.value)
    pulse_time += random.normal(0, deviation, geom.n_pixels)

    timing = timing_parameters(geom,
                               image=np.ones(geom.n_pixels),
                               pulse_time=pulse_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)
Exemple #12
0
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'])

    geom = CameraGeometry.from_name('LSTCam-002')
    foclen = OpticsDescription.from_name('LST').equivalent_focal_length
    dl1_container = DL1ParametersContainer()
    parameters_to_update = list(HillasParametersContainer().keys())
    parameters_to_update.extend(['wl', 'r', 'leakage', 'n_islands', 'intercept', 'time_gradient'])

    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']
                pulse_time = row['pulse_time']
                signal_pixels = tailcuts_clean(geom, image, **config['tailcut'])
                if image[signal_pixels].shape[0] > 0:
                    num_islands, island_labels = number_of_islands(geom, signal_pixels)
                    hillas = hillas_parameters(geom[signal_pixels], image[signal_pixels])

                    dl1_container.fill_hillas(hillas)
                    dl1_container.set_timing_features(geom[signal_pixels],
                                                      image[signal_pixels],
                                                      pulse_time[signal_pixels],
                                                      hillas)
                    dl1_container.set_leakage(geom, image, signal_pixels)
                    dl1_container.n_islands = num_islands
                    dl1_container.wl = dl1_container.width / dl1_container.length
                    width = np.rad2deg(np.arctan2(dl1_container.width, foclen))
                    length = np.rad2deg(np.arctan2(dl1_container.length, foclen))
                    dl1_container.width = width.value
                    dl1_container.length = length.value
                    dl1_container.r = np.sqrt(dl1_container.x**2 + dl1_container.y**2)

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

            output.root[dl1_params_lstcam_key][:] = params
Exemple #13
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)
Exemple #14
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(
        leakage1_pixel=0.1,
        leakage2_pixel=0.1,
        leakage1_intensity=0.1,
        leakage2_intensity=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 "leakage2_pixel" in df.columns
def test_ignore_negative():
    grad = 2.0
    intercept = 1.0

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

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

    timing = timing_parameters(
        geom,
        image,
        peakpos=intercept + grad * geom.pix_x.value,
        hillas_parameters=hillas,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit)
    assert_allclose(timing.intercept, intercept)
def test_psi_0():
    """
    Simple test that gradient fitting gives expected answers for perfect
    gradient
    """
    grad = 2.0
    intercept = 1.0

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

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peakpos=intercept + grad * geom.pix_x.value,
        hillas_parameters=hillas,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit)
    assert_allclose(timing.intercept, intercept)
def test_psi_20():

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

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

    timing = timing_parameters(
        geom,
        image=np.ones(geom.n_pixels),
        peakpos=intercept + grad * (np.cos(psi) * geom.pix_x.value
                                    + np.sin(psi) * geom.pix_y.value),
        hillas_parameters=hillas,
    )

    # Test we get the values we put in back out again
    assert_allclose(timing.slope, grad / geom.pix_x.unit)
    assert_allclose(timing.intercept, intercept)
Exemple #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(
        leakage1_pixel=0.1,
        leakage2_pixel=0.1,
        leakage1_intensity=0.1,
        leakage2_intensity=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 'leakage2_pixel' in df.columns
def get_hillas_container(row):
    h = HillasParametersContainer()
    h.x = row['x'] * 28 * u.m
    h.y = row['y'] * 28 * u.m
    h.r = row['r'] * 28 * u.m
    h.phi = Angle(row['phi'] * u.rad)
    h.width = row['width'] * u.m
    h.length = row['length'] * u.m
    h.psi = Angle(row['psi'] * u.rad)
    h.skewness = row['skewness']
    h.kurtosis = row['kurtosis']
    return h
Exemple #20
0
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([
        'wl', 'r', 'leakage1_intensity', 'leakage2_intensity',
        'leakage1_pixel', 'leakage2_pixel', 'concentration_cog',
        'concentration_core', 'concentration_pixel', 'n_pixels', 'n_islands',
        'intercept', 'time_gradient'
    ])

    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']
                pulse_time = row['pulse_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],
                        pulse_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.value
                    dl1_container.length = length.value
                    dl1_container.r = np.sqrt(dl1_container.x**2 +
                                              dl1_container.y**2)

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

            output.root[dl1_params_lstcam_key][:] = params