def subarray():
    subarray = SubarrayDescription(
        "test array",
        tel_positions={
            1: np.zeros(3) * u.m,
            2: np.zeros(3) * u.m
        },
        tel_descriptions={
            1:
            TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                           camera_name="CHEC"),
            2:
            TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                           camera_name="CHEC"),
        },
    )

    # Create reference pulse
    sample_width = 0.5
    reference_pulse_sample_width = sample_width / 10
    reference_pulse_duration = 100
    pulse_sigma = 6
    ref_time = np.arange(0, reference_pulse_duration,
                         reference_pulse_sample_width)
    reference_pulse = norm.pdf(ref_time, reference_pulse_duration / 2,
                               pulse_sigma)

    readout = subarray.tel[1].camera.readout
    readout.reference_pulse_shape = np.array([reference_pulse])
    readout.reference_pulse_sample_width = u.Quantity(
        reference_pulse_sample_width, u.ns)
    readout.sampling_rate = u.Quantity(1 / sample_width, u.GHz)
    return subarray
Exemple #2
0
def camera_waveforms():
    subarray = SubarrayDescription(
        "test array",
        tel_positions={
            1: np.zeros(3) * u.m,
            2: np.ones(3) * u.m
        },
        tel_descriptions={
            1:
            TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                           camera_name="CHEC"),
            2:
            TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                           camera_name="CHEC"),
        })

    n_pixels = subarray.tel[1].camera.n_pixels
    n_samples = 96
    mid = n_samples // 2
    pulse_sigma = 6
    random = np.random.RandomState(1)

    x = np.arange(n_samples)

    # Randomize times
    t_pulse = random.uniform(mid - 10, mid + 10, n_pixels)[:, np.newaxis]

    # Create pulses
    y = norm.pdf(x, t_pulse, pulse_sigma)

    # Randomize amplitudes
    y *= random.uniform(100, 1000, n_pixels)[:, np.newaxis]

    return y, subarray
Exemple #3
0
def test_hdf(example_subarray):
    import tables

    with tempfile.NamedTemporaryFile(suffix=".hdf5") as f:

        example_subarray.to_hdf(f.name)
        read = SubarrayDescription.from_hdf(f.name)

        assert example_subarray == read

        # test that subarrays without name (v0.8.0) work:
        with tables.open_file(f.name, "r+") as hdf:
            del hdf.root.configuration.instrument.subarray._v_attrs.name

        no_name = SubarrayDescription.from_hdf(f.name)
        assert no_name.name == "Unknown"

    # test with a subarray that has two different telescopes with the same
    # camera
    tel = {
        1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"),
        2: TelescopeDescription.from_name(optics_name="SST-GCT", camera_name="CHEC"),
    }
    pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m}

    array = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel)

    with tempfile.NamedTemporaryFile(suffix=".hdf5") as f:

        array.to_hdf(f.name)
        read = SubarrayDescription.from_hdf(f.name)

        assert array == read
def test_hdf(example_subarray):
    import tables

    with tempfile.NamedTemporaryFile(suffix=".hdf5") as f:

        example_subarray.to_hdf(f.name)
        read = SubarrayDescription.from_hdf(f.name)

        assert example_subarray == read

        # test we can write the read subarray
        read.to_hdf(f.name, overwrite=True)

        for tel_id, tel in read.tel.items():
            assert (tel.camera.geometry.frame.focal_length ==
                    tel.optics.equivalent_focal_length)

            # test if transforming works
            tel.camera.geometry.transform_to(TelescopeFrame())

        # test that subarrays without name (v0.8.0) work:
        with tables.open_file(f.name, "r+") as hdf:
            del hdf.root.configuration.instrument.subarray._v_attrs.name

        no_name = SubarrayDescription.from_hdf(f.name)
        assert no_name.name == "Unknown"

    # test with a subarray that has two different telescopes with the same
    # camera
    tel = {
        1:
        TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                       camera_name="CHEC"),
        2:
        TelescopeDescription.from_name(optics_name="SST-GCT",
                                       camera_name="CHEC"),
    }
    pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m}

    array = SubarrayDescription("test array",
                                tel_positions=pos,
                                tel_descriptions=tel)

    with tempfile.NamedTemporaryFile(suffix=".hdf5") as f:

        array.to_hdf(f.name)
        read = SubarrayDescription.from_hdf(f.name)

        assert array == read
def plot_telescope_layout(tel_layout_file_name):
    layout_file = "/Users/alicedonini/PycharmProjects/Pointing_tool/layout-3AL4-BN15-MST.txt"
    grd_coords = pd.read_csv(layout_file,
                             header=None,
                             delimiter="  ",
                             names=["x", "y", "z"],
                             engine='python')

    # convert to m
    grd_coords = grd_coords / 100

    # create a dictionary with the tel position on the ground by tel_id and the tel description
    tel_descr = {}
    G_coords = {}
    for tel_id, coord in enumerate(grd_coords.values, 1):
        G_coords[tel_id] = coord * u.m
        tel_descr[tel_id] = TelescopeDescription.from_name(
            optics_name='MST', camera_name='NectarCam')

    # create the subarray
    sub = SubarrayDescription(name="Baseline only MST",
                              tel_positions=G_coords,
                              tel_descriptions=tel_descr)
    #sub.info()
    #sub.to_table(kind='optics')

    # display the array
    plt.figure(num=None, figsize=(7, 7), facecolor='w', edgecolor='k')
    disp = ArrayDisplay(sub, tel_scale=3.0)

    return sub
Exemple #6
0
def test_hdf_duplicate_string_repr(tmp_path):
    """Test writing and reading of a subarray with two telescopes that
    are different but have the same name.
    """
    # test with a subarray that has two different telescopes with the same
    # camera
    tel1 = TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam")

    # second telescope is almost the same and as the same str repr
    tel2 = deepcopy(tel1)
    # e.g. one mirror fell off
    tel2.optics.num_mirror_tiles = tel1.optics.num_mirror_tiles - 1

    array = SubarrayDescription(
        "test array",
        tel_positions={1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m},
        tel_descriptions={1: tel1, 2: tel2},
    )

    # defensive checks to make sure we are actually testing this
    assert len(array.telescope_types) == 2
    assert str(tel1) == str(tel2)
    assert tel1 != tel2

    path = tmp_path / "subarray.h5"
    array.to_hdf(path)
    read = SubarrayDescription.from_hdf(path)
    assert array == read
    assert (
        read.tel[1].optics.num_mirror_tiles == read.tel[2].optics.num_mirror_tiles + 1
    )
Exemple #7
0
def test_hdf_same_camera(tmp_path):
    """Test writing / reading subarray to hdf5 with a subarray that has two
    different telescopes with the same camera
    """
    tel = {
        1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"),
        2: TelescopeDescription.from_name(optics_name="SST-GCT", camera_name="CHEC"),
    }
    pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m}

    array = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel)

    path = tmp_path / "subarray.h5"
    array.to_hdf(path)
    read = SubarrayDescription.from_hdf(path)
    assert array == read
Exemple #8
0
def subarray_lst():
    telid = 1
    subarray = SubarrayDescription(
        "test array lst",
        tel_positions={1: np.zeros(3) * u.m, 2: np.ones(3) * u.m},
        tel_descriptions={
            1: TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam"),
            2: TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam"),
        },
    )

    n_pixels = subarray.tel[telid].camera.geometry.n_pixels
    n_samples = 30
    selected_gain_channel = np.zeros(n_pixels, dtype=np.int)

    return subarray, telid, selected_gain_channel, n_pixels, n_samples
Exemple #9
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 #10
0
def test_muon_efficiency_fit():
    from ctapipe.instrument import TelescopeDescription, SubarrayDescription
    from ctapipe.coordinates import TelescopeFrame, CameraFrame
    from ctapipe.image.muon.intensity_fitter import image_prediction, MuonIntensityFitter

    telescope = TelescopeDescription.from_name('LST', 'LSTCam')
    subarray = SubarrayDescription(
        'LSTMono', {0: [0, 0, 0] * u.m}, {0: telescope},
    )

    center_x = 0.8 * u.deg
    center_y = 0.4 * u.deg
    radius = 1.2 * u.deg
    ring_width = 0.05 * u.deg
    impact_parameter = 5 * u.m
    phi = 0 * u.rad
    efficiency = 0.5

    focal_length = telescope.optics.equivalent_focal_length
    geom = telescope.camera.geometry
    mirror_radius = np.sqrt(telescope.optics.mirror_area / np.pi)
    pixel_diameter = 2 * u.rad * (np.sqrt(geom.pix_area / np.pi) / focal_length).to_value(u.dimensionless_unscaled)

    tel = CameraFrame(
        x=geom.pix_x,
        y=geom.pix_y,
        focal_length=focal_length,
        rotation=geom.cam_rotation,
    ).transform_to(TelescopeFrame())
    x = tel.fov_lon
    y = tel.fov_lat

    image = image_prediction(
        mirror_radius,
        hole_radius=0 * u.m,
        impact_parameter=impact_parameter,
        phi=phi,
        center_x=center_x,
        center_y=center_y,
        radius=radius,
        ring_width=ring_width,
        pixel_x=x,
        pixel_y=y,
        pixel_diameter=pixel_diameter[0]
    )

    fitter = MuonIntensityFitter(subarray=subarray)
    result = fitter(
        tel_id=0,
        center_x=center_x,
        center_y=center_y,
        radius=radius,
        image=image * efficiency,
        pedestal=np.full_like(image, 1.1)
    )

    assert u.isclose(result.impact, impact_parameter, rtol=0.05)
    assert u.isclose(result.width, ring_width, rtol=0.05)
    assert u.isclose(result.optical_efficiency, efficiency, rtol=0.05)
Exemple #11
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()
Exemple #12
0
def get_telescope_description(optics_name: str,
                              cam_name: str) -> TelescopeDescription:
    if telescope_descriptions.get(optics_name) is None:
        telescope_descriptions[optics_name] = dict()
    if telescope_descriptions[optics_name].get(cam_name) is None:
        telescope_descriptions[optics_name][
            cam_name] = TelescopeDescription.from_name(optics_name, cam_name)
    return telescope_descriptions[optics_name][cam_name]
 def __init__(self, config=None, tool=None, **kwargs):
     super().__init__(config=config, tool=tool, **kwargs)
     from protozfits import File
     self.file = File(self.input_url)
     # TODO: Correct pixel ordering
     self._tel_desc = TelescopeDescription.from_name(
         optics_name='SST-1M',
         camera_name='DigiCam'
     )
Exemple #14
0
def subarray_1_LST():
    subarray = SubarrayDescription(
        "One LST",
        tel_positions={1: np.zeros(3) * u.m},
        tel_descriptions={
            1:
            TelescopeDescription.from_name(optics_name="LST",
                                           camera_name="LSTCam")
        },
    )
    return subarray
Exemple #15
0
def test_tel_ids_to_mask(example_subarray):
    lst = TelescopeDescription.from_name("LST", "LSTCam")
    subarray = SubarrayDescription(
        "someone_counted_in_binary",
        tel_positions={1: [0, 0, 0] * u.m, 10: [50, 0, 0] * u.m},
        tel_descriptions={1: lst, 10: lst},
    )

    assert np.all(subarray.tel_ids_to_mask([]) == [False, False])
    assert np.all(subarray.tel_ids_to_mask([1]) == [True, False])
    assert np.all(subarray.tel_ids_to_mask([10]) == [False, True])
    assert np.all(subarray.tel_ids_to_mask([1, 10]) == [True, True])
Exemple #16
0
def example_subarray(n_tels=10):
    """ generate a simple subarray for testing purposes """
    pos = {}
    tel = {}

    for tel_id in range(1, n_tels + 1):
        tel[tel_id] = TelescopeDescription.from_name(
            optics_name="MST", camera_name="NectarCam"
        )
        pos[tel_id] = np.random.uniform(-100, 100, size=3) * u.m

    return SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel)
Exemple #17
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 #18
0
def subarray():

    lst = TelescopeDescription.from_name("LST", "LSTCam")
    tels = [lst] * 4

    positions = {
        1: [0, 0, 0] * u.m,
        2: [50, 0, 0] * u.m,
        3: [0, 50, 0] * u.m,
        4: [50, 50, 0] * u.m,
    }
    descriptions = {i: t for i, t in enumerate(tels, start=1)}

    return SubarrayDescription("test", positions, descriptions)
Exemple #19
0
def test_pedestal_calculator():
    """ test of PedestalIntegrator """
    from lstchain.calib.camera.pedestals import PedestalIntegrator

    tel_id = 0
    n_events = 10
    n_gain = 2
    n_pixels = 1855
    ped_level = 300

    subarray = SubarrayDescription(
        "test array",
        tel_positions={0: np.zeros(3) * u.m},
        tel_descriptions={
            0: TelescopeDescription.from_name(
                optics_name="SST-ASTRI", camera_name="CHEC"
            ),
        },
    )
    subarray.tel[0].camera.readout.reference_pulse_shape = np.ones((1, 2))
    subarray.tel[0].camera.readout.reference_pulse_sample_width = u.Quantity(1, u.ns)

    config = Config({
        "FixedWindowSum": {
          "apply_integration_correction": False,
        }
    })
    ped_calculator = PedestalIntegrator(charge_product="FixedWindowSum",
                                        config=config,
                                        sample_size=n_events,
                                        tel_id=tel_id,
                                        subarray=subarray)
    # create one event
    data = ArrayEventContainer()
    data.meta['origin'] = 'test'

    # fill the values necessary for the pedestal calculation
    data.mon.tel[tel_id].pixel_status.hardware_failing_pixels = np.zeros(
        (n_gain, n_pixels), dtype=bool
    )
    data.r1.tel[tel_id].waveform = np.full((2, n_pixels, 40), ped_level)
    data.trigger.time = Time(0, format='mjd', scale='tai')
    while ped_calculator.num_events_seen < n_events:
        if ped_calculator.calculate_pedestals(data):
            assert data.mon.tel[tel_id].pedestal
            assert np.mean(data.mon.tel[tel_id].pedestal.charge_median) == (
                ped_calculator.extractor.window_width.tel[tel_id] * ped_level
            )
            assert np.mean(data.mon.tel[tel_id].pedestal.charge_std) == 0
Exemple #20
0
def test_get_tel_ids(example_subarray):
    """Test for SubarrayDescription.get_tel_ids"""
    subarray = example_subarray
    sst = TelescopeDescription.from_name("SST-ASTRI", "CHEC")

    telescopes = [1, 2, "MST_MST_FlashCam", sst]
    tel_ids = subarray.get_tel_ids(telescopes)

    true_tel_ids = (subarray.get_tel_ids_for_type("MST_MST_FlashCam") +
                    subarray.get_tel_ids_for_type(sst) + [1, 2])

    assert sorted(tel_ids) == sorted(true_tel_ids)

    # test invalid telescope type
    with pytest.raises(Exception):
        tel_ids = subarray.get_tel_ids(["It's a-me, Mario!"])
Exemple #21
0
def test_telescope_component():
    from ctapipe.core import TelescopeComponent
    from ctapipe.instrument import SubarrayDescription, TelescopeDescription

    subarray = SubarrayDescription(
        "test",
        tel_positions={1: [0, 0, 0] * u.m},
        tel_descriptions={1: TelescopeDescription.from_name("LST", "LSTCam")},
    )

    class Base(TelescopeComponent):
        pass

    class Sub(Base):
        pass

    assert isinstance(Base.from_name("Sub", subarray=subarray), Sub)
Exemple #22
0
def test_sw_pulse_lst():
    """
    Test function of sliding window extractor for LST camera pulse shape with
    the correction for the integration window completeness
    """

    # prepare array with 1 LST
    subarray = SubarrayDescription(
        "LST1",
        tel_positions={1: np.zeros(3) * u.m},
        tel_descriptions={
            1:
            TelescopeDescription.from_name(optics_name="LST",
                                           camera_name="LSTCam")
        },
    )

    telid = list(subarray.tel.keys())[0]

    n_pixels = subarray.tel[telid].camera.geometry.n_pixels
    n_samples = 40
    readout = subarray.tel[telid].camera.readout

    random = np.random.RandomState(1)
    min_charge = 100
    max_charge = 1000
    charge_true = random.uniform(min_charge, max_charge, n_pixels)
    time_true = random.uniform(n_samples // 2 - 1, n_samples // 2 + 1,
                               n_pixels) / readout.sampling_rate.to_value(
                                   u.GHz)

    waveform_model = WaveformModel.from_camera_readout(readout)
    waveform = waveform_model.get_waveform(charge_true, time_true, n_samples)
    selected_gain_channel = np.zeros(charge_true.size, dtype=np.int8)

    # define extractor
    config = Config({"SlidingWindowMaxSum": {"window_width": 8}})
    extractor = SlidingWindowMaxSum(subarray=subarray)
    extractor = ImageExtractor.from_name("SlidingWindowMaxSum",
                                         subarray=subarray,
                                         config=config)

    dl1: DL1CameraContainer = extractor(waveform, telid, selected_gain_channel)
    print(dl1.image / charge_true)
    assert_allclose(dl1.image, charge_true, rtol=0.02)
    assert dl1.is_valid
Exemple #23
0
def test_pedestal_calculator():
    """ test of PedestalIntegrator """

    tel_id = 0
    n_events = 10
    n_gain = 2
    n_pixels = 1855
    ped_level = 300

    subarray = SubarrayDescription(
        "test array",
        tel_positions={0: np.zeros(3) * u.m},
        tel_descriptions={
            0: TelescopeDescription.from_name(
                optics_name="SST-ASTRI", camera_name="CHEC"
            ),
        },
    )
    subarray.tel[0].camera.readout.reference_pulse_shape = np.ones((1, 2))
    subarray.tel[0].camera.readout.reference_pulse_sample_width = u.Quantity(1, u.ns)

    ped_calculator = PedestalIntegrator(
        subarray=subarray,
        charge_product="FixedWindowSum",
        sample_size=n_events,
        tel_id=tel_id,
    )
    # create one event
    data = EventAndMonDataContainer()
    data.meta["origin"] = "test"

    # fill the values necessary for the pedestal calculation
    data.mon.tel[tel_id].pixel_status.hardware_failing_pixels = np.zeros(
        (n_gain, n_pixels), dtype=bool
    )
    data.r1.tel[tel_id].waveform = np.full((2, n_pixels, 40), ped_level)
    data.r1.tel[tel_id].trigger_time = 1000

    while ped_calculator.num_events_seen < n_events:
        if ped_calculator.calculate_pedestals(data):
            assert data.mon.tel[tel_id].pedestal
            assert np.mean(data.mon.tel[tel_id].pedestal.charge_median) == (
                ped_calculator.extractor.window_width.tel[0] * ped_level
            )
            assert np.mean(data.mon.tel[tel_id].pedestal.charge_std) == 0
Exemple #24
0
def test_subarray_description():
    pos = {}
    tel = {}
    n_tels = 10

    for tel_id in range(1, n_tels + 1):
        tel[tel_id] = TelescopeDescription.from_name(
            optics_name="MST",
            camera_name="NectarCam",
        )
        pos[tel_id] = np.random.uniform(-100, 100, size=3) * u.m

    sub = SubarrayDescription(
        "test array",
        tel_positions=pos,
        tel_descriptions=tel
    )

    sub.peek()

    assert len(sub.telescope_types) == 1

    assert str(sub) == "test array"
    assert sub.num_tels == n_tels
    assert len(sub.tel_ids) == n_tels
    assert sub.tel_ids[0] == 1
    assert sub.tel[1].camera is not None
    assert 0 not in sub.tel  # check that there is no tel 0 (1 is first above)
    assert len(sub.to_table()) == n_tels
    assert len(sub.camera_types) == 1  # only 1 camera type
    assert sub.camera_types[0] == 'NectarCam'
    assert sub.optics_types[0].equivalent_focal_length.to_value(u.m) == 16.0
    assert sub.telescope_types[0] == 'MST:NectarCam'
    assert sub.tel_coords
    assert isinstance(sub.tel_coords, SkyCoord)
    assert len(sub.tel_coords) == n_tels

    subsub = sub.select_subarray("newsub", [2, 3, 4, 6])
    assert subsub.num_tels == 4
    assert set(subsub.tels.keys()) == {2, 3, 4, 6}
    assert subsub.tel_indices[6] == 3
    assert subsub.tel_ids[3] == 6

    assert len(sub.to_table(kind='optics')) == 1
Exemple #25
0
def test_scts():
    from ctapipe.instrument import TelescopeDescription, SubarrayDescription
    from ctapipe.image.muon.intensity_fitter import MuonIntensityFitter

    telescope = TelescopeDescription.from_name('SST-ASTRI', 'CHEC')
    subarray = SubarrayDescription(
        'ssts', {0: [0, 0, 0] * u.m}, {0: telescope},
    )

    fitter = MuonIntensityFitter(subarray=subarray)
    with pytest.raises(NotImplementedError):
        fitter(
            tel_id=0,
            center_x=0 * u.deg,
            center_y=2 * u.deg,
            radius=1.3 * u.deg,
            image=np.zeros(telescope.camera.geometry.n_pixels),
            pedestal=np.zeros(telescope.camera.geometry.n_pixels)
        )
Exemple #26
0
def test_estimator_results():
    """
    creating some planes pointing in different directions (two
    north-south, two east-west) and that have a slight position errors (+-
    0.1 m in one of the four cardinal directions """
    horizon_frame = AltAz()

    p1 = SkyCoord(alt=43 * u.deg, az=45 * u.deg, frame=horizon_frame)
    p2 = SkyCoord(alt=47 * u.deg, az=45 * u.deg, frame=horizon_frame)
    circle1 = HillasPlane(p1=p1, p2=p2, telescope_position=[0, 1, 0] * u.m)

    p1 = SkyCoord(alt=44 * u.deg, az=90 * u.deg, frame=horizon_frame)
    p2 = SkyCoord(alt=46 * u.deg, az=90 * u.deg, frame=horizon_frame)
    circle2 = HillasPlane(p1=p1, p2=p2, telescope_position=[1, 0, 0] * u.m)

    p1 = SkyCoord(alt=44.5 * u.deg, az=45 * u.deg, frame=horizon_frame)
    p2 = SkyCoord(alt=46.5 * u.deg, az=45 * u.deg, frame=horizon_frame)
    circle3 = HillasPlane(p1=p1, p2=p2, telescope_position=[0, -1, 0] * u.m)

    p1 = SkyCoord(alt=43.5 * u.deg, az=90 * u.deg, frame=horizon_frame)
    p2 = SkyCoord(alt=45.5 * u.deg, az=90 * u.deg, frame=horizon_frame)
    circle4 = HillasPlane(p1=p1, p2=p2, telescope_position=[-1, 0, 0] * u.m)

    # Create a dummy subarray
    # (not used here, but required to initialize the reconstructor)
    subarray = SubarrayDescription(
        "test array",
        tel_positions={1: np.zeros(3) * u.m},
        tel_descriptions={
            1:
            TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                           camera_name="CHEC")
        },
    )

    # creating the fit class and setting the the great circle member
    fit = HillasReconstructor(subarray)
    hillas_planes = {1: circle1, 2: circle2, 3: circle3, 4: circle4}

    # performing the direction fit with the minimisation algorithm
    # and a seed that is perpendicular to the up direction
    dir_fit_minimise, _ = fit.estimate_direction(hillas_planes)
    print("direction fit test minimise:", dir_fit_minimise)
Exemple #27
0
def test_subarray_description():
    pos = {}
    tel = {}
    n_tels = 10

    for tel_id in range(1, n_tels + 1):
        tel[tel_id] = TelescopeDescription.from_name(
            optics_name="MST",
            camera_name="NectarCam",
        )
        pos[tel_id] = np.random.uniform(-100, 100, size=3) * u.m

    sub = SubarrayDescription(
        "test array",
        tel_positions=pos,
        tel_descriptions=tel
    )

    assert len(sub.telescope_types) == 1

    assert str(sub) == "test array"
    assert sub.num_tels == n_tels
    assert len(sub.tel_ids) == n_tels
    assert sub.tel_ids[0] == 1
    assert sub.tel[1].camera is not None
    assert 0 not in sub.tel  # check that there is no tel 0 (1 is first above)
    assert len(sub.to_table()) == n_tels
    assert len(sub.camera_types) == 1  # only 1 camera type
    assert sub.camera_types[0] == 'NectarCam'
    assert sub.optics_types[0].equivalent_focal_length.to_value(u.m) == 16.0
    assert sub.telescope_types[0] == 'MST:NectarCam'
    assert sub.tel_coords
    assert isinstance(sub.tel_coords, SkyCoord)
    assert len(sub.tel_coords) == n_tels

    subsub = sub.select_subarray("newsub", [2, 3, 4, 6])
    assert subsub.num_tels == 4
    assert set(subsub.tels.keys()) == {2, 3, 4, 6}
    assert subsub.tel_indices[6] == 3
    assert subsub.tel_ids[3] == 6

    assert len(sub.to_table(kind='optics')) == 1
Exemple #28
0
def test_image_cleaner(method):
    """ Test that we can construct and use a component-based ImageCleaner"""

    config = Config({
        "TailcutsImageCleaner": {
            "boundary_threshold_pe": 5.0,
            "picture_threshold_pe": 10.0,
        },
        "MARSImageCleaner": {
            "boundary_threshold_pe": 5.0,
            "picture_threshold_pe": 10.0,
        },
        "FACTImageCleaner": {
            "boundary_threshold_pe": 5.0,
            "picture_threshold_pe": 10.0,
            "time_limit_ns": 6.0,
        },
    })

    tel = TelescopeDescription.from_name("MST", "NectarCam")
    subarray = SubarrayDescription(name="test",
                                   tel_positions={1: None},
                                   tel_descriptions={1: tel})

    clean = ImageCleaner.from_name(method, config=config, subarray=subarray)

    image = np.zeros_like(tel.camera.geometry.pix_x.value, dtype=np.float)
    image[10:30] = 20.0
    image[31:40] = 8.0
    times = np.linspace(-5, 10, image.shape[0])

    mask = clean(tel_id=1, image=image, arrival_times=times)

    # we're not testing the algorithm here, just that it does something (for the
    # algorithm tests, see test_cleaning.py
    assert np.count_nonzero(mask) > 0
Exemple #29
0
import matplotlib.pylab as plt
import numpy as np
from astropy import units as u
from ctapipe.instrument import CameraGeometry
from ctapipe.visualization import CameraDisplay
from ctapipe.image import toymodel
from matplotlib.animation import FuncAnimation
from ctapipe.instrument import TelescopeDescription

if __name__ == '__main__':

    plt.style.use("ggplot")
    fig, ax = plt.subplots()

    # load the camera
    tel = TelescopeDescription.from_name("SST-1M", "DigiCam")
    print(tel, tel.optics.effective_focal_length)
    geom = tel.camera

    # poor-man's coordinate transform from telscope to camera frame (it's
    # better to use ctapipe.coordiantes when they are stable)
    scale = tel.optics.effective_focal_length.to(geom.pix_x.unit).value
    fov = np.deg2rad(4.0)
    maxwid = np.deg2rad(0.01)
    maxlen = np.deg2rad(0.03)

    disp = CameraDisplay(geom, ax=ax)
    disp.cmap = plt.cm.terrain
    disp.add_colorbar(ax=ax)

    def update(frame):
def test_flasherflatfieldcalculator():
    """test of flasherFlatFieldCalculator"""
    tel_id = 0
    n_gain = 2
    n_events = 10
    n_pixels = 1855
    ff_level = 10000

    subarray = SubarrayDescription(
        "test array",
        tel_positions={0: np.zeros(3) * u.m},
        tel_descriptions={
            0:
            TelescopeDescription.from_name(optics_name="SST-ASTRI",
                                           camera_name="CHEC"),
        },
    )
    subarray.tel[0].camera.readout.reference_pulse_shape = np.ones((1, 2))
    subarray.tel[0].camera.readout.reference_pulse_sample_width = u.Quantity(
        1, u.ns)

    config = Config({
        "FixedWindowSum": {
            "window_shift": 5,
            "window_width": 10,
            "peak_index": 20,
            "apply_integration_correction": False,
        }
    })
    ff_calculator = FlasherFlatFieldCalculator(subarray=subarray,
                                               charge_product="FixedWindowSum",
                                               sample_size=n_events,
                                               tel_id=tel_id,
                                               config=config)
    # create one event
    data = ArrayEventContainer()
    data.meta['origin'] = 'test'
    data.trigger.time = Time(0, format='mjd', scale='tai')
    # initialize mon and r1 data
    data.mon.tel[tel_id].pixel_status.hardware_failing_pixels = np.zeros(
        (n_gain, n_pixels), dtype=bool)
    data.mon.tel[tel_id].pixel_status.pedestal_failing_pixels = np.zeros(
        (n_gain, n_pixels), dtype=bool)
    data.mon.tel[tel_id].pixel_status.flatfield_failing_pixels = np.zeros(
        (n_gain, n_pixels), dtype=bool)
    data.r1.tel[tel_id].waveform = np.zeros((n_gain, n_pixels, 40),
                                            dtype=np.float32)
    # data.r1.tel[tel_id].trigger_time = 1000

    # flat-field signal put == delta function of height ff_level at sample 20
    data.r1.tel[tel_id].waveform[:, :, 20] = ff_level
    print(data.r1.tel[tel_id].waveform[0, 0, 20])

    # First test: good event
    while ff_calculator.num_events_seen < n_events:
        if ff_calculator.calculate_relative_gain(data):
            assert data.mon.tel[tel_id].flatfield

            print(data.mon.tel[tel_id].flatfield)
            assert np.mean(
                data.mon.tel[tel_id].flatfield.charge_median) == ff_level
            assert np.mean(
                data.mon.tel[tel_id].flatfield.relative_gain_median) == 1
            assert np.mean(
                data.mon.tel[tel_id].flatfield.relative_gain_std) == 0

    # Second test: introduce some failing pixels
    failing_pixels_id = np.array([10, 20, 30, 40])
    data.r1.tel[tel_id].waveform[:, failing_pixels_id, :] = 0
    data.mon.tel[
        tel_id].pixel_status.pedestal_failing_pixels[:,
                                                     failing_pixels_id] = True

    while ff_calculator.num_events_seen < n_events:
        if ff_calculator.calculate_relative_gain(data):

            # working pixel have good gain
            assert (
                data.mon.tel[tel_id].flatfield.relative_gain_median[0, 0] == 1)

            # bad pixels do non influence the gain
            assert np.mean(
                data.mon.tel[tel_id].flatfield.relative_gain_std) == 0
Exemple #31
0
    def _display_camera_animation(self):
        # plt.style.use("ggplot")
        fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7))
        ax = plt.subplot(111)

        # load the camera
        tel = TelescopeDescription.from_name(optics_name=self.optics,
                                             camera_name=self.camera)
        geom = tel.camera

        # poor-man's coordinate transform from telscope to camera frame (it's
        # better to use ctapipe.coordiantes when they are stable)
        scale = tel.optics.effective_focal_length.to(geom.pix_x.unit).value
        fov = np.deg2rad(4.0)
        maxwid = np.deg2rad(0.01)
        maxlen = np.deg2rad(0.03)

        disp = CameraDisplay(geom,
                             ax=ax,
                             autoupdate=True,
                             title="{}, f={}".format(
                                 tel, tel.optics.effective_focal_length))
        disp.cmap = plt.cm.terrain

        def update(frame):

            centroid = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid) * scale
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 50
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            image, sig, bg = toymodel.make_toymodel_shower_image(
                geom, model.pdf, intensity=intens, nsb_level_pe=5000)

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image / 80.0)
                for ii in range(3):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels

            self.log.debug("count = {}, image sum={} max={}".format(
                self._counter, image.sum(), image.max()))
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-100, 4000)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [
                ax,
            ]

        self.anim = FuncAnimation(fig,
                                  update,
                                  interval=self.delay,
                                  blit=self.blit)
        plt.show()
Exemple #32
0
import matplotlib.pylab as plt
import numpy as np
from astropy import units as u
from matplotlib.animation import FuncAnimation

from ctapipe.image import toymodel
from ctapipe.instrument import TelescopeDescription
from ctapipe.visualization import CameraDisplay

if __name__ == '__main__':

    plt.style.use("ggplot")
    fig, ax = plt.subplots()

    # load the camera
    tel = TelescopeDescription.from_name("SST-1M", "DigiCam")
    geom = tel.camera

    fov = 0.3
    maxwid = 0.05
    maxlen = 0.1

    disp = CameraDisplay(geom, ax=ax)
    disp.cmap = 'inferno'
    disp.add_colorbar(ax=ax)

    def update(frame):
        x, y = np.random.uniform(-fov, fov, size=2)
        width = np.random.uniform(0.01, maxwid)
        length = np.random.uniform(width, maxlen)
        angle = np.random.uniform(0, 180)
Exemple #33
0
    def _display_camera_animation(self):
        # plt.style.use("ggplot")
        fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7))
        ax = plt.subplot(111)

        # load the camera
        tel = TelescopeDescription.from_name(optics_name=self.optics,
                                             camera_name=self.camera)
        geom = tel.camera

        # poor-man's coordinate transform from telscope to camera frame (it's
        # better to use ctapipe.coordiantes when they are stable)
        foclen = tel.optics.equivalent_focal_length.to(geom.pix_x.unit).value
        fov = np.deg2rad(4.0)
        scale = foclen
        minwid = np.deg2rad(0.1)
        maxwid = np.deg2rad(0.3)
        maxlen = np.deg2rad(0.5)

        self.log.debug("scale={} m, wid=({}-{})".format(scale, minwid, maxwid))

        disp = CameraDisplay(
            geom, ax=ax, autoupdate=True,
            title="{}, f={}".format(tel, tel.optics.equivalent_focal_length)
        )
        disp.cmap = plt.cm.terrain

        def update(frame):


            centroid = np.random.uniform(-fov, fov, size=2) * scale
            width = np.random.uniform(0, maxwid-minwid) * scale + minwid
            length = np.random.uniform(0, maxlen) * scale + width
            angle = np.random.uniform(0, 360)
            intens = np.random.exponential(2) * 500
            model = toymodel.generate_2d_shower_model(centroid=centroid,
                                                      width=width,
                                                      length=length,
                                                      psi=angle * u.deg)
            self.log.debug(
                "Frame=%d width=%03f length=%03f intens=%03d",
                frame, width, length, intens
            )

            image, sig, bg = toymodel.make_toymodel_shower_image(
                geom,
                model.pdf,
                intensity=intens,
                nsb_level_pe=3,
            )

            # alternate between cleaned and raw images
            if self._counter == self.cleanframes:
                plt.suptitle("Image Cleaning ON")
                self.imclean = True
            if self._counter == self.cleanframes * 2:
                plt.suptitle("Image Cleaning OFF")
                self.imclean = False
                self._counter = 0
                disp.clear_overlays()

            if self.imclean:
                cleanmask = tailcuts_clean(geom, image,
                                           picture_thresh=10.0,
                                           boundary_thresh=5.0)
                for ii in range(2):
                    dilate(geom, cleanmask)
                image[cleanmask == 0] = 0  # zero noise pixels
                try:
                    hillas = hillas_parameters(geom, image)
                    disp.overlay_moments(hillas, with_label=False,
                                         color='red', alpha=0.7,
                                         linewidth=2, linestyle='dashed')
                except HillasParameterizationError:
                    disp.clear_overlays()
                    pass

            self.log.debug("Frame=%d  image_sum=%.3f max=%.3f",
                           self._counter, image.sum(), image.max())
            disp.image = image

            if self.autoscale:
                disp.set_limits_percent(95)
            else:
                disp.set_limits_minmax(-5, 200)

            disp.axes.figure.canvas.draw()
            self._counter += 1
            return [ax, ]

        frames = None if self.num_events == 0 else self.num_events
        repeat = True if self.num_events == 0 else False

        self.log.info("Running for {} frames".format(frames))
        self.anim = FuncAnimation(fig, update,
                                  interval=self.delay,
                                  frames=frames,
                                  repeat=repeat,
                                  blit=self.blit)

        if self.display:
            plt.show()