Beispiel #1
0
def test_equals():
    cam1 = CameraGeometry.from_name("LSTCam")
    cam2 = CameraGeometry.from_name("LSTCam")
    cam3 = CameraGeometry.from_name("ASTRICam")

    assert cam1 is not cam2
    assert cam1 == cam2
    assert cam1 != cam3
Beispiel #2
0
def test_border_pixels():
    from ctapipe.instrument.camera import CameraGeometry

    cam = CameraGeometry.from_name("LSTCam")

    assert np.sum(cam.get_border_pixel_mask(1)) == 168
    assert np.sum(cam.get_border_pixel_mask(2)) == 330

    cam = CameraGeometry.from_name("ASTRICam")
    assert np.sum(cam.get_border_pixel_mask(1)) == 212
    assert np.sum(cam.get_border_pixel_mask(2)) == 408

    assert cam.get_border_pixel_mask(1)[0]
    assert cam.get_border_pixel_mask(1)[2351]
    assert not cam.get_border_pixel_mask(1)[521]
def test_convert_geometry(cam_id, rot):

    geom = CameraGeometry.from_name(cam_id)

    if geom.pix_type=='rectangular':
        return  # skip non-hexagonal cameras, since they don't need conversion

    model = generate_2d_shower_model(centroid=(0.4, 0), width=0.01, length=0.03,
                                     psi="25d")

    _,image,_ = make_toymodel_shower_image(geom, model.pdf,
                                           intensity=50,
                                           nsb_level_pe=100)

    hillas_0 = hillas_parameters(geom.pix_x, geom.pix_y, image)

    geom2d, image2d = convert_geometry_1d_to_2d(geom, image,
                                                 geom.cam_id+str(rot),
                                                 add_rot=-2)
    geom1d, image1d = convert_geometry_back(geom2d, image2d,
                                            geom.cam_id+str(rot),
                                            add_rot=rot)
    hillas_1 = hillas_parameters(geom1d.pix_x, geom1d.pix_y, image1d)

    if __name__ == "__main__":
        plot_cam(geom, geom2d, geom1d, image, image2d, image1d)

    assert np.abs(hillas_1.phi - hillas_0.phi).deg < 1.0
Beispiel #4
0
def create_sample_image(psi='-30d'):

    seed(10)

    # set up the sample image using a HESS camera geometry (since it's easy
    # to load)
    geom = CameraGeometry.from_name("LSTCam")

    # make a toymodel shower model
    model = toymodel.generate_2d_shower_model(centroid=(0.2, 0.3),
                                              width=0.001, length=0.01,
                                              psi=psi)

    # generate toymodel image in camera for this shower model.
    image, signal, noise = toymodel.make_toymodel_shower_image(geom, model.pdf,
                                                               intensity=50,
                                                               nsb_level_pe=100)

    # denoise the image, so we can calculate hillas params
    clean_mask = tailcuts_clean(geom, image, 10,
                                5)  # pedvars = 1 and core and boundary
    # threshold in pe
    image[~clean_mask] = 0

    # Pixel values in the camera
    pix_x = geom.pix_x.value
    pix_y = geom.pix_y.value

    return pix_x, pix_y, image
Beispiel #5
0
def test_intensity():
    from ctapipe.image.toymodel import Gaussian

    np.random.seed(0)
    geom = CameraGeometry.from_name('LSTCam')

    x, y = u.Quantity([0.2, 0.3], u.m)
    width = 0.05 * u.m
    length = 0.15 * u.m
    intensity = 50
    psi = '30d'

    # make a toymodel shower model
    model = Gaussian(x=x, y=y, width=width, length=length, psi=psi)

    image, signal, noise = model.generate_image(
        geom, intensity=intensity, nsb_level_pe=5,
    )

    # test if signal reproduces given cog values
    assert np.average(geom.pix_x.to_value(u.m), weights=signal) == approx(0.2, rel=0.15)
    assert np.average(geom.pix_y.to_value(u.m), weights=signal) == approx(0.3, rel=0.15)

    # test if signal reproduces given width/length values
    cov = np.cov(geom.pix_x.value, geom.pix_y.value, aweights=signal)
    eigvals, eigvecs = np.linalg.eigh(cov)

    assert np.sqrt(eigvals[0]) == approx(width.to_value(u.m), rel=0.15)
    assert np.sqrt(eigvals[1]) == approx(length.to_value(u.m), rel=0.15)

    # test if total intensity is inside in 99 percent confidence interval
    assert poisson(intensity).ppf(0.05) <= signal.sum() <= poisson(intensity).ppf(0.95)
Beispiel #6
0
def test_neighbor_pixels(cam_id):
    """
    test if each camera has a reasonable number of neighbor pixels (4 for
    rectangular, and 6 for hexagonal.  Other than edge pixels, the majority
    should have the same value
    """

    geom = CameraGeometry.from_name(cam_id)
    n_pix = len(geom.pix_id)
    n_neighbors = [len(x) for x in geom.neighbors]


    if geom.pix_type.startswith('hex'):
        assert n_neighbors.count(6) > 0.5 * n_pix
        assert n_neighbors.count(6) > n_neighbors.count(4)

    if geom.pix_type.startswith('rect'):
        assert n_neighbors.count(4) > 0.5 * n_pix
        assert n_neighbors.count(5) == 0
        assert n_neighbors.count(6) == 0

    # whipple has inhomogenious pixels that mess with pixel neighborhood
    # calculation
    if cam_id != 'Whipple490':
        assert np.all(geom.neighbor_matrix == geom.neighbor_matrix.T)
        assert n_neighbors.count(1) == 0  # no pixel should have a single neighbor
Beispiel #7
0
def test_slicing_rotation(cam_id):
    cam = CameraGeometry.from_name(cam_id)
    cam.rotate('25d')

    sliced1 = cam[5:10]

    assert sliced1.pix_x[0] == cam.pix_x[5]
Beispiel #8
0
def test_skewed():
    from ctapipe.image.toymodel import SkewedGaussian
    # test if the parameters we calculated for the skew normal
    # distribution produce the correct moments
    np.random.seed(0)
    geom = CameraGeometry.from_name('LSTCam')

    x, y = u.Quantity([0.2, 0.3], u.m)
    width = 0.05 * u.m
    length = 0.15 * u.m
    intensity = 50
    psi = '30d'
    skewness = 0.3

    model = SkewedGaussian(
        x=x, y=y, width=width,
        length=length, psi=psi, skewness=skewness
    )
    image, signal, _ = model.generate_image(
        geom, intensity=intensity, nsb_level_pe=5,
    )

    a, loc, scale = model._moments_to_parameters()
    mean, var, skew = skewnorm(a=a, loc=loc, scale=scale).stats(moments='mvs')

    assert np.isclose(mean, 0)
    assert np.isclose(var, length.to_value(u.m)**2)
    assert np.isclose(skew, skewness)
Beispiel #9
0
def camera_waveforms():
    camera = CameraGeometry.from_name("CHEC")

    n_pixels = camera.n_pixels
    n_samples = 96
    mid = n_samples // 2
    pulse_sigma = 6
    r_hi = np.random.RandomState(1)
    r_lo = np.random.RandomState(2)

    x = np.arange(n_samples)

    # Randomize times
    t_pulse_hi = r_hi.uniform(mid - 10, mid + 10, n_pixels)[:, np.newaxis]
    t_pulse_lo = r_lo.uniform(mid + 10, mid + 20, n_pixels)[:, np.newaxis]

    # Create pulses
    y_hi = norm.pdf(x, t_pulse_hi, pulse_sigma)
    y_lo = norm.pdf(x, t_pulse_lo, pulse_sigma)

    # Randomize amplitudes
    y_hi *= r_hi.uniform(100, 1000, n_pixels)[:, np.newaxis]
    y_lo *= r_lo.uniform(100, 1000, n_pixels)[:, np.newaxis]

    y = np.stack([y_hi, y_lo])

    return y, camera
Beispiel #10
0
def test_fact_image_cleaning():
    # use LST pixel geometry
    geom = CameraGeometry.from_name("LSTCam")
    # create some signal pixels
    values = np.zeros(len(geom))
    timing = np.zeros(len(geom))
    signal_pixels = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                             10, 11, 12, 13, 14, 37, 38, 111, 222])
    values[signal_pixels] = 5
    timing[signal_pixels] = 10
    # manipulate some of those
    values[[1, 2]] = 3
    values[7] = 1
    timing[[5, 6, 13, 111]] = 20

    mask = cleaning.fact_image_cleaning(geom,
                                        values,
                                        timing,
                                        boundary_threshold=2,
                                        picture_threshold=4,
                                        min_number_neighbors=2,
                                        time_limit=5)

    expected_pixels = np.array([0, 1, 2, 3, 4, 8, 9, 10, 11])
    expected_mask = np.zeros(len(geom)).astype(bool)
    expected_mask[expected_pixels] = 1
    assert_allclose(mask, expected_mask)
Beispiel #11
0
def test_intensity():
    from .. import toymodel

    np.random.seed(0)

    geom = CameraGeometry.from_name('LSTCam')

    width = 0.05
    length = 0.15
    intensity = 50

    # make a toymodel shower model
    model = toymodel.generate_2d_shower_model(
        centroid=(0.2, 0.3),
        width=width, length=length,
        psi='30d',
    )

    image, signal, noise = toymodel.make_toymodel_shower_image(
        geom, model.pdf, intensity=intensity, nsb_level_pe=5,
    )

    # test if signal reproduces given cog values
    assert np.average(geom.pix_x.value, weights=signal) == approx(0.2, rel=0.15)
    assert np.average(geom.pix_y.value, weights=signal) == approx(0.3, rel=0.15)

    # test if signal reproduces given width/length values
    cov = np.cov(geom.pix_x.value, geom.pix_y.value, aweights=signal)
    eigvals, eigvecs = np.linalg.eigh(cov)

    assert np.sqrt(eigvals[0]) == approx(width, rel=0.15)
    assert np.sqrt(eigvals[1]) == approx(length, rel=0.15)

    # test if total intensity is inside in 99 percent confidence interval
    assert poisson(intensity).ppf(0.05) <= signal.sum() <= poisson(intensity).ppf(0.95)
Beispiel #12
0
def create_sample_image(
        psi='-30d',
        x=0.2 * u.m,
        y=0.3 * u.m,
        width=0.05 * u.m,
        length=0.15 * u.m,
        intensity=1500
):
    seed(10)

    geom = CameraGeometry.from_name('LSTCam')

    # make a toymodel shower model
    model = toymodel.Gaussian(x=x, y=y, width=width, length=length, psi=psi)

    # generate toymodel image in camera for this shower model.
    image, _, _ = model.generate_image(
        geom,
        intensity=1500,
        nsb_level_pe=3,
    )

    # calculate pixels likely containing signal
    clean_mask = tailcuts_clean(geom, image, 10, 5)

    return geom, image, clean_mask
def test_convert_geometry_mock(cam_id, rot):
    """here we use a different key for the back conversion to trigger the mock conversion
    """

    geom = CameraGeometry.from_name(cam_id)
    image = create_mock_image(geom)
    hillas_0 = hillas_parameters(geom, image)

    if geom.pix_type == 'hexagonal':
        convert_geometry_1d_to_2d = convert_geometry_hex1d_to_rect2d
        convert_geometry_back = convert_geometry_rect2d_back_to_hexe1d

        geom2d, image2d = convert_geometry_1d_to_2d(geom, image, key=None,
                                                    add_rot=rot)
        geom1d, image1d = convert_geometry_back(geom2d, image2d,
                                                "_".join([geom.cam_id,
                                                          str(rot), "mock"]),
                                                add_rot=rot)
    else:
        # originally rectangular geometries don't need a buffer and therefore no mock
        # conversion
        return

    hillas_1 = hillas_parameters(geom, image1d)
    assert np.abs(hillas_1.phi - hillas_0.phi).deg < 1.0
Beispiel #14
0
def test_neighbor_pixels():
    hexgeom = CameraGeometry.from_name("LSTCam")
    recgeom = CameraGeometry.make_rectangular()

    # most pixels should have 4 neighbors for rectangular geometry and 6 for
    # hexagonal
    assert int(median(recgeom.neighbor_matrix.sum(axis=1))) == 4
    assert int(median(hexgeom.neighbor_matrix.sum(axis=1))) == 6
Beispiel #15
0
def test_known_camera_names():
    cams = CameraGeometry.get_known_camera_names()
    assert len(cams) > 4
    assert 'FlashCam' in cams
    assert 'NectarCam' in cams

    for cam in cams:
        geom = CameraGeometry.from_name(cam)
        geom.info()
Beispiel #16
0
def test_known_camera_names():
    cams = CameraGeometry.get_known_camera_names()
    assert len(cams) > 4
    assert 'FlashCam' in cams
    assert 'NectarCam' in cams

    for cam in cams:
        geom = CameraGeometry.from_name(cam)
        geom.info()
Beispiel #17
0
    def _generator(self):

        # container for LST data
        self.data = LSTDataContainer()
        self.data.meta['input_url'] = self.input_url
        self.data.meta['max_events'] = self.max_events

        # fill LST data from the CameraConfig table
        self.fill_lst_service_container_from_zfile()

        # Instrument information
        for tel_id in self.data.lst.tels_with_data:

            assert (tel_id == 0 or tel_id == 1) # only LST1 (for the moment id = 0)

            # optics info from standard optics.fits.gz file
            optics = OpticsDescription.from_name("LST")

            # camera info from LSTCam-[geometry_version].camgeom.fits.gz file
            geometry_version = 2
            camera = CameraGeometry.from_name("LSTCam", geometry_version)

            tel_descr = TelescopeDescription(
                name='LST', type='LST', optics=optics, camera=camera
            )

            self.n_camera_pixels = tel_descr.camera.n_pixels
            tels = {tel_id: tel_descr}

            # LSTs telescope position taken from MC from the moment
            tel_pos = {tel_id: [50., 50., 16] * u.m}

        subarray = SubarrayDescription("LST1 subarray")
        subarray.tels = tels
        subarray.positions = tel_pos

        self.data.inst.subarray = subarray

        # initialize general monitoring container
        self.initialize_mon_container()

        # loop on events
        for count, event in enumerate(self.multi_file):

            self.data.count = count

            # fill specific LST event data
            self.fill_lst_event_container_from_zfile(event)

            # fill general monitoring data
            self.fill_mon_container_from_zfile(event)

            # fill general R0 data
            self.fill_r0_container_from_zfile(event)

            yield self.data
def test_ChaudhuriKunduRingFitter():

    geom = CameraGeometry.from_name('HESS-I')

    ring_rad = np.deg2rad(
        1. * u.deg) * 15.  # make sure this is in camera coordinates
    ring_width = np.deg2rad(0.05 * u.deg) * 15.
    geom_pixall = np.empty(geom.pix_x.shape + (2, ))
    geom_pixall[..., 0] = geom.pix_x.value
    geom_pixall[..., 1] = geom.pix_y.value

    # image = generate_muon_model(geom_pixall, ring_rad, ring_width, 0.3, 0.2)
    muon_model = partial(toymodel.generate_muon_model,
                         radius=ring_rad.value,
                         width=ring_width.value,
                         centre_x=-0.2,
                         centre_y=-0.3)

    toymodel_image, toy_signal, toy_noise = \
        toymodel.make_toymodel_shower_image(geom, muon_model)

    clean_toy_mask = tailcuts_clean(geom,
                                    toymodel_image,
                                    boundary_thresh=5,
                                    picture_thresh=10)

    # camera_coord = CameraFrame(x=x,y=y,z=np.zeros(x.shape)*u.m,
    # focal_length = event.inst.optical_foclen[telid], rotation=geom.pix_rotation)
    muonring = muon_ring_finder.ChaudhuriKunduRingFitter(None)

    x = np.rad2deg((geom.pix_x.value / 15.) * u.rad)  # .value
    y = np.rad2deg((geom.pix_y.value / 15.) * u.rad)  # .value

    muonringparam = muonring.fit(x, y, toymodel_image * clean_toy_mask)

    dist = np.sqrt(
        np.power(x - muonringparam.ring_center_x, 2) +
        np.power(y - muonringparam.ring_center_y, 2))
    ring_dist = np.abs(dist - muonringparam.ring_radius)
    muonringparam = muonring.fit(
        x, y, toymodel_image * (ring_dist < muonringparam.ring_radius * 0.4))

    dist = np.sqrt(
        np.power(x - muonringparam.ring_center_x, 2) +
        np.power(y - muonringparam.ring_center_y, 2))
    ring_dist = np.abs(dist - muonringparam.ring_radius)
    muonringparam = muonring.fit(
        x, y, toymodel_image * (ring_dist < muonringparam.ring_radius * 0.4))

    print('Fitted ring radius', muonringparam.ring_radius, 'c.f.', ring_rad)
    print('Fitted ring centre', muonringparam.ring_center_x,
          muonringparam.ring_center_y)

    assert muonringparam.ring_radius is not ring_rad  # .value
    assert muonringparam.ring_center_x is not -0.2
    assert muonringparam.ring_center_y is not -0.3
Beispiel #19
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 = np.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=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}
    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()
Beispiel #20
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
        geom = CameraGeometry.from_name(self.camera)
        disp = CameraDisplay(geom, ax=ax, autoupdate=True, )
        disp.cmap = plt.cm.terrain

        def update(frame):

            centroid = np.random.uniform(-0.5, 0.5, size=2)
            width = np.random.uniform(0, 0.01)
            length = np.random.uniform(0, 0.03) + 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()
Beispiel #21
0
def test_to_and_from_table():
    geom = CameraGeometry.from_name("LSTCam")
    tab = geom.to_table()
    geom2 = geom.from_table(tab)

    assert geom.cam_id == geom2.cam_id
    assert (geom.pix_x == geom2.pix_x).all()
    assert (geom.pix_y == geom2.pix_y).all()
    assert (geom.pix_area == geom2.pix_area).all()
    assert geom.pix_type == geom2.pix_type
Beispiel #22
0
def test_overlay_disp_vector():

    from ctapipe.image import hillas_parameters

    geom = CameraGeometry.from_name('LSTCam')
    image = np.random.rand(geom.n_pixels)
    display = CameraDisplay(geom, image)
    hillas = hillas_parameters(geom, image)
    disp = disp_parameters_event(hillas, 0.1 * u.m, 0.3 * u.m)
    overlay_disp_vector(display, disp, hillas)
Beispiel #23
0
def test_known_camera_names():
    """ Check that we can get a list of known camera names """
    cams = CameraGeometry.get_known_camera_names()
    assert len(cams) > 4
    assert 'FlashCam' in cams
    assert 'NectarCam' in cams

    for cam in cams:
        geom = CameraGeometry.from_name(cam)
        geom.info()
Beispiel #24
0
def test_to_and_from_table():
    geom = CameraGeometry.from_name("LSTCam")
    tab = geom.to_table()
    geom2 = geom.from_table(tab)

    assert geom.cam_id == geom2.cam_id
    assert (geom.pix_x == geom2.pix_x).all()
    assert (geom.pix_y == geom2.pix_y).all()
    assert (geom.pix_area == geom2.pix_area).all()
    assert geom.pix_type == geom2.pix_type
Beispiel #25
0
def test_camera_coordinate_transform(camera_name):
    '''test conversion of the coordinates stored in a camera frame'''
    from ctapipe.coordinates import EngineeringCameraFrame

    geom = CameraGeometry.from_name(camera_name)
    trans_geom = geom.transform_to(EngineeringCameraFrame())

    unit = geom.pix_x.unit
    assert np.allclose(geom.pix_x.to_value(unit), -trans_geom.pix_y.to_value(unit))
    assert np.allclose(geom.pix_y.to_value(unit), -trans_geom.pix_x.to_value(unit))
Beispiel #26
0
    def __init__(self, config=None, tool=None, **kwargs):
        """
        Constructor

        Parameters
        ----------
        config: traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            Set to None if no configuration to pass.
        tool: ctapipe.core.Tool
            Tool executable that is calling this component.
            Passes the correct logger to the component.
            Set to None if no Tool to pass.
        kwargs: dict
            Additional parameters to be passed.
            NOTE: The file mask of the data to read can be passed with
            the 'input_url' parameter.
        """

        file_list = glob.glob(kwargs['input_url'])
        file_list.sort()

        # EventSource can not handle file wild cards as input_url
        # To overcome this we substitute the input_url with first file matching
        # the specified file mask.
        del kwargs['input_url']
        super().__init__(config=config, tool=tool, input_url=file_list[0], **kwargs)

        try:
            import uproot
        except ImportError:
            msg = "The `uproot` python module is required to access the MAGIC data"
            self.log.error(msg)
            raise

        # Retrieving the list of run numbers corresponding to the data files
        run_numbers = list(map(self._get_run_number, file_list))
        self.run_numbers = np.unique(run_numbers)

        # # Setting up the current run with the first run present in the data
        # self.current_run = self._set_active_run(run_number=0)
        self.current_run = None
        
        # MAGIC telescope positions in m wrt. to the center of CTA simulations
        self.magic_tel_positions = {
            1: [-27.24, -146.66, 50.00] * u.m,
            2: [-96.44, -96.77, 51.00] * u.m
        }
        # MAGIC telescope description
        optics = OpticsDescription.from_name('MAGIC')
        geom = CameraGeometry.from_name('MAGICCam')
        self.magic_tel_description = TelescopeDescription(optics=optics, camera=geom)
        self.magic_tel_descriptions = {1: self.magic_tel_description, 2: self.magic_tel_description}
        self.magic_subarray = SubarrayDescription('MAGIC', self.magic_tel_positions, self.magic_tel_descriptions)
Beispiel #27
0
def test_to_and_from_table():
    """ Check converting to and from an astropy Table """
    geom = CameraGeometry.from_name("LSTCam")
    tab = geom.to_table()
    geom2 = geom.from_table(tab)

    assert geom.cam_id == geom2.cam_id
    assert (geom.pix_x == geom2.pix_x).all()
    assert (geom.pix_y == geom2.pix_y).all()
    assert (geom.pix_area == geom2.pix_area).all()
    assert geom.pix_type == geom2.pix_type
Beispiel #28
0
def test_hillas_overlay():
    from ctapipe.visualization import CameraDisplay

    disp = CameraDisplay(CameraGeometry.from_name("LSTCam"))
    hillas = CameraHillasParametersContainer(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)
Beispiel #29
0
def test_camera_display_single():
    """ test CameraDisplay functionality """
    from ..mpl import CameraDisplay

    geom = CameraGeometry.from_name("LSTCam")
    disp = CameraDisplay(geom)
    image = ones(len(geom.pix_x), dtype=float)
    disp.image = image
    disp.add_colorbar()
    disp.cmap = 'spectral'
    disp.set_limits_minmax(0, 10)
    disp.set_limits_percent(95)
def test_ChaudhuriKunduRingFitter():

    geom = CameraGeometry.from_name('LSTCam')
    focal_length = u.Quantity(28, u.m)

    ring_radius = u.Quantity(0.4, u.m)  # make sure this is in camera coordinates
    ring_width = u.Quantity(0.03, u.m)
    center_x = u.Quantity(-0.2, u.m)
    center_y = u.Quantity(-0.3, u.m)

    muon_model = RingGaussian(
        x=center_x, y=center_y,
        sigma=ring_width, radius=ring_radius,
    )

    image, _, _ = muon_model.generate_image(
        geom, intensity=1000, nsb_level_pe=5,
    )

    clean_mask = tailcuts_clean(
        geom, image, boundary_thresh=5, picture_thresh=10
    )

    fitter = muon_ring_finder.ChaudhuriKunduRingFitter()

    x = geom.pix_x / focal_length * u.rad
    y = geom.pix_y / focal_length * u.rad

    # fit 3 times, first iteration use cleaning, after that use
    # distance to previous fit result
    result = None
    for _ in range(3):
        if result is None:
            mask = clean_mask
        else:
            dist = np.sqrt((x - result.ring_center_x)**2 + (y - result.ring_center_y)**2)
            ring_dist = np.abs(dist - result.ring_radius)
            mask = ring_dist < (result.ring_radius * 0.4)

        result = fitter.fit(x[mask], y[mask], image[mask])

    assert np.isclose(
        result.ring_radius.to_value(u.rad), ring_radius / focal_length,
        rtol=0.05,
    )
    assert np.isclose(
        result.ring_center_x.to_value(u.rad), center_x / focal_length,
        rtol=0.05
    )
    assert np.isclose(
        result.ring_center_y.to_value(u.rad), center_y / focal_length,
        rtol=0.05,
    )
Beispiel #31
0
def test_camera_display_single():
    """ test CameraDisplay functionality """
    from ..mpl import CameraDisplay

    geom = CameraGeometry.from_name("LSTCam")
    disp = CameraDisplay(geom)
    image = ones(len(geom.pix_x), dtype=float)
    disp.image = image
    disp.add_colorbar()
    disp.cmap = 'spectral'
    disp.set_limits_minmax(0, 10)
    disp.set_limits_percent(95)
Beispiel #32
0
def test_skewness():
    np.random.seed(42)

    geom = CameraGeometry.from_name('LSTCam')

    width = 0.03 * u.m
    length = 0.15 * u.m
    intensity = 2500

    xs = u.Quantity([0.5, 0.5, -0.5, -0.5], u.m)
    ys = u.Quantity([0.5, -0.5, 0.5, -0.5], u.m)
    psis = Angle([-90, -45, 0, 45, 90], unit='deg')
    skews = [0, 0.3, 0.6]

    for x, y, psi, skew in itertools.product(xs, ys, psis, skews):
        # make a toymodel shower model
        model = toymodel.SkewedGaussian(
            x=x,
            y=y,
            width=width,
            length=length,
            psi=psi,
            skewness=skew,
        )

        _, signal, _ = model.generate_image(
            geom,
            intensity=intensity,
            nsb_level_pe=5,
        )

        result = hillas_parameters(geom, signal)

        assert quantity_approx(result.x, x, rel=0.1)
        assert quantity_approx(result.y, y, rel=0.1)

        assert quantity_approx(result.width, width, rel=0.1)
        assert quantity_approx(result.length, length, rel=0.1)

        psi_same = result.psi.to_value(u.deg) == approx(psi.deg, abs=3)
        psi_opposite = abs(result.psi.to_value(u.deg) - psi.deg) == approx(
            180.0, abs=3)
        assert psi_same or psi_opposite

        # if we have delta the other way around, we get a negative sign for skewness
        # skewness is quite imprecise, maybe we could improve this somehow
        if psi_same:
            assert result.skewness == approx(skew, abs=0.3)
        else:
            assert result.skewness == approx(-skew, abs=0.3)

        assert signal.sum() == result.intensity
def test_apply_time_delta_cleaning():
    geom = CameraGeometry.from_name("LSTCam")
    peak_time = np.zeros(geom.n_pixels, dtype=np.float64)

    pixel = 40
    neighbors = geom.neighbors[pixel]
    peak_time[neighbors] = 32.0
    peak_time[pixel] = 30.0
    mask = peak_time > 0

    # Test unchanged
    td_mask = cleaning.apply_time_delta_cleaning(geom,
                                                 mask,
                                                 peak_time,
                                                 min_number_neighbors=1,
                                                 time_limit=5)
    test_mask = mask.copy()
    assert (test_mask == td_mask).all()

    # Test time_limit
    noise_neighbor = neighbors[0]
    peak_time[noise_neighbor] += 10
    td_mask = cleaning.apply_time_delta_cleaning(geom,
                                                 mask,
                                                 peak_time,
                                                 min_number_neighbors=1,
                                                 time_limit=5)
    test_mask = mask.copy()
    test_mask[noise_neighbor] = 0
    assert (test_mask == td_mask).all()

    # Test min_number_neighbors
    td_mask = cleaning.apply_time_delta_cleaning(geom,
                                                 mask,
                                                 peak_time,
                                                 min_number_neighbors=4,
                                                 time_limit=5)
    test_mask = mask.copy()
    test_mask[neighbors] = 0
    assert (test_mask == td_mask).all()

    # Test unselected neighbors
    mask[156] = 0
    peak_time[noise_neighbor] -= 10
    td_mask = cleaning.apply_time_delta_cleaning(geom,
                                                 mask,
                                                 peak_time,
                                                 min_number_neighbors=3,
                                                 time_limit=5)
    test_mask = mask.copy()
    test_mask[[41, 157]] = 0
    assert (test_mask == td_mask).all()
    def _generator(self):

        # container for NectarCAM data
        self.data = NectarCAMDataContainer()
        self.data.meta['input_url'] = self.input_url

        # fill data from the CameraConfig table
        self.fill_nectarcam_service_container_from_zfile()


        # Instrument information
        for tel_id in self.data.nectarcam.tels_with_data:
            assert (tel_id == 0)  # only one telescope for the moment (id = 0)

            # optics info from standard optics.fits.gz file
            optics = OpticsDescription.from_name("MST")
            optics.tel_subtype = ''  # to correct bug in reading

            # camera info from NectarCam-[geometry_version].camgeom.fits.gz file
            geometry_version = 2
            camera = CameraGeometry.from_name("NectarCam", geometry_version)

            tel_descr = TelescopeDescription(optics, camera)

            tel_descr.optics.tel_subtype = ''  # to correct bug in reading

            self.n_camera_pixels = tel_descr.camera.n_pixels
            tels = {tel_id: tel_descr}

            # LSTs telescope position
            tel_pos = {tel_id: [0., 0., 0] * u.m}


        self.subarray = SubarrayDescription("MST prototype subarray")
        self.subarray.tels = tels
        self.subarray.positions = tel_pos

        self.data.inst.subarray = self.subarray



        # loop on events
        for count, event in enumerate(self.multi_file):

            self.data.count = count

            # fill specific NectarCAM event data
            self.fill_nectarcam_event_container_from_zfile(event)

            # fill general R0 data
            self.fill_r0_container_from_zfile(event)
            yield self.data
Beispiel #35
0
def test_write_read(tmpdir):
    """ Check that serialization to disk doesn't lose info """
    filename = str(tmpdir.join('testcamera.fits.gz'))

    geom = CameraGeometry.from_name("LSTCam")
    geom.to_table().write(filename, overwrite=True)
    geom2 = geom.from_table(filename)

    assert geom.cam_id == geom2.cam_id
    assert (geom.pix_x == geom2.pix_x).all()
    assert (geom.pix_y == geom2.pix_y).all()
    assert (geom.pix_area == geom2.pix_area).all()
    assert geom.pix_type == geom2.pix_type
Beispiel #36
0
def test_camera_display_multiple():
    """ create a figure with 2 subplots, each with a CameraDisplay """
    from ..mpl import CameraDisplay
    
    geom = CameraGeometry.from_name("LSTCam")
    fig, ax = plt.subplots(2, 1)

    d1 = CameraDisplay(geom, ax=ax[0])
    d2 = CameraDisplay(geom, ax=ax[1])

    image = ones(len(geom.pix_x), dtype=float)
    d1.image = image
    d2.image = image
Beispiel #37
0
def test_pixel_shapes(pix_type):
    """ test CameraDisplay functionality """
    from ..mpl_camera import CameraDisplay

    geom = CameraGeometry.from_name("LSTCam")
    geom.pix_type = pix_type

    disp = CameraDisplay(geom)
    image = np.random.normal(size=len(geom.pix_x))
    disp.image = image
    disp.add_colorbar()
    disp.highlight_pixels([1, 2, 3, 4, 5])
    disp.add_ellipse(centroid=(0, 0), width=0.1, length=0.1, angle=0.1)
Beispiel #38
0
def test_write_read(tmpdir):

    filename = str(tmpdir.join('testcamera.fits.gz'))

    geom = CameraGeometry.from_name("LSTCam")
    geom.to_table().write(filename, overwrite=True)
    geom2 = geom.from_table(filename)

    assert geom.cam_id == geom2.cam_id
    assert (geom.pix_x == geom2.pix_x).all()
    assert (geom.pix_y == geom2.pix_y).all()
    assert (geom.pix_area == geom2.pix_area).all()
    assert geom.pix_type == geom2.pix_type
Beispiel #39
0
def test_slicing():
    geom = CameraGeometry.from_name("NectarCam")
    sliced1 = geom[100:200]

    assert len(sliced1.pix_x) == 100
    assert len(sliced1.pix_y) == 100
    assert len(sliced1.pix_area) == 100
    assert len(sliced1.pix_id) == 100

    sliced2 = geom[[5, 7, 8, 9, 10]]
    assert sliced2.pix_id[0] == 5
    assert sliced2.pix_id[1] == 7
    assert len(sliced2.pix_x) == 5
Beispiel #40
0
def test_slicing():
    geom = CameraGeometry.from_name("NectarCam")
    sliced1 = geom[100:200]

    assert len(sliced1.pix_x) == 100
    assert len(sliced1.pix_y) == 100
    assert len(sliced1.pix_area) == 100
    assert len(sliced1.pix_id) == 100

    sliced2 = geom[[5, 7, 8, 9, 10]]
    assert sliced2.pix_id[0] == 5
    assert sliced2.pix_id[1] == 7
    assert len(sliced2.pix_x) == 5
Beispiel #41
0
def test_camera_display_multiple():
    """ create a figure with 2 subplots, each with a CameraDisplay """
    from ..mpl_camera import CameraDisplay

    geom = CameraGeometry.from_name("LSTCam")
    fig, ax = plt.subplots(2, 1)

    d1 = CameraDisplay(geom, ax=ax[0])
    d2 = CameraDisplay(geom, ax=ax[1])

    image = ones(len(geom.pix_x), dtype=float)
    d1.image = image
    d2.image = image
Beispiel #42
0
def test_write_read(tmpdir):

    filename = str(tmpdir.join('testcamera.fits.gz'))

    geom = CameraGeometry.from_name("LSTCam")
    geom.to_table().write(filename, overwrite=True)
    geom2 = geom.from_table(filename)

    assert geom.cam_id == geom2.cam_id
    assert (geom.pix_x == geom2.pix_x).all()
    assert (geom.pix_y == geom2.pix_y).all()
    assert (geom.pix_area == geom2.pix_area).all()
    assert geom.pix_type == geom2.pix_type
Beispiel #43
0
def test_with_toy():
    np.random.seed(42)

    geom = CameraGeometry.from_name("LSTCam")

    width = 0.03 * u.m
    length = 0.15 * u.m
    width_uncertainty = 0.00094 * u.m
    length_uncertainty = 0.00465 * u.m
    intensity = 500

    xs = u.Quantity([0.5, 0.5, -0.5, -0.5], u.m)
    ys = u.Quantity([0.5, -0.5, 0.5, -0.5], u.m)
    psis = Angle([-90, -45, 0, 45, 90], unit="deg")

    for x, y in zip(xs, ys):
        for psi in psis:

            # make a toymodel shower model
            model = toymodel.Gaussian(
                x=x,
                y=y,
                width=width,
                length=length,
                psi=psi,
            )

            image, signal, noise = model.generate_image(
                geom,
                intensity=intensity,
                nsb_level_pe=5,
            )

            result = hillas_parameters(geom, signal)

            assert u.isclose(result.x, x, rtol=0.1)
            assert u.isclose(result.y, y, rtol=0.1)

            assert u.isclose(result.width, width, rtol=0.1)
            assert u.isclose(result.width_uncertainty,
                             width_uncertainty,
                             rtol=0.4)
            assert u.isclose(result.length, length, rtol=0.1)
            assert u.isclose(result.length_uncertainty,
                             length_uncertainty,
                             rtol=0.4)
            assert (result.psi.to_value(u.deg) == approx(
                psi.deg, abs=2)) or abs(result.psi.to_value(u.deg) -
                                        psi.deg) == approx(180.0, abs=2)

            assert signal.sum() == result.intensity
Beispiel #44
0
def test_intensity(seed, monkeypatch):
    """
    Test generation of the toymodel roughly follows the given intensity.

    Tests once with passing a custom rng instance, once with relying on the
    modules rng.
    """
    from ctapipe.image import toymodel

    geom = CameraGeometry.from_name("LSTCam")

    x, y = u.Quantity([0.2, 0.3], u.m)
    width = 0.05 * u.m
    length = 0.15 * u.m
    intensity = 200
    psi = "30d"

    # make sure we set a fixed seed for this test even when testing the
    # API without giving the rng
    monkeypatch.setattr(toymodel, "TOYMODEL_RNG", np.random.default_rng(0))

    # make a toymodel shower model
    model = toymodel.Gaussian(x=x, y=y, width=width, length=length, psi=psi)

    if seed is None:
        _, signal, _ = model.generate_image(geom,
                                            intensity=intensity,
                                            nsb_level_pe=5)
    else:
        rng = np.random.default_rng(seed)
        _, signal, _ = model.generate_image(geom,
                                            intensity=intensity,
                                            nsb_level_pe=5,
                                            rng=rng)

    # test if signal reproduces given cog values
    assert np.average(geom.pix_x.to_value(u.m),
                      weights=signal) == approx(0.2, rel=0.15)
    assert np.average(geom.pix_y.to_value(u.m),
                      weights=signal) == approx(0.3, rel=0.15)

    # test if signal reproduces given width/length values
    cov = np.cov(geom.pix_x.value, geom.pix_y.value, aweights=signal)
    eigvals, _ = np.linalg.eigh(cov)

    assert np.sqrt(eigvals[0]) == approx(width.to_value(u.m), rel=0.15)
    assert np.sqrt(eigvals[1]) == approx(length.to_value(u.m), rel=0.15)

    # test if total intensity is inside in 99 percent confidence interval
    assert poisson(intensity).ppf(0.05) <= signal.sum() <= poisson(
        intensity).ppf(0.95)
Beispiel #45
0
def test_convert_geometry(cam_id, rot):

    geom = CameraGeometry.from_name(cam_id)

    model = generate_2d_shower_model(centroid=(0.4, 0),
                                     width=0.01,
                                     length=0.03,
                                     psi="25d")

    _, image, _ = make_toymodel_shower_image(geom,
                                             model.pdf,
                                             intensity=50,
                                             nsb_level_pe=100)

    hillas_0 = hillas_parameters(geom, image)

    if geom.pix_type == 'hexagonal':
        convert_geometry_1d_to_2d = convert_geometry_hex1d_to_rect2d
        convert_geometry_back = convert_geometry_rect2d_back_to_hexe1d

        geom2d, image2d = convert_geometry_1d_to_2d(geom,
                                                    image,
                                                    geom.cam_id + str(rot),
                                                    add_rot=rot)
        geom1d, image1d = convert_geometry_back(geom2d,
                                                image2d,
                                                geom.cam_id + str(rot),
                                                add_rot=rot)

    else:
        if geom.cam_id == "ASTRICam":
            convert_geometry_1d_to_2d = astri_to_2d_array
            convert_geometry_back = array_2d_to_astri
        elif geom.cam_id == "CHEC":
            convert_geometry_1d_to_2d = chec_to_2d_array
            convert_geometry_back = array_2d_to_chec
        else:
            print("camera {geom.cam_id} not implemented")
            return

        image2d = convert_geometry_1d_to_2d(image)
        image1d = convert_geometry_back(image2d)

    hillas_1 = hillas_parameters(geom, image1d)

    # if __name__ == "__main__":
    #     plot_cam(geom, geom2d, geom1d, image, image2d, image1d)
    #     plt.tight_layout()
    #     plt.pause(.1)

    assert np.abs(hillas_1.phi - hillas_0.phi).deg < 1.0
Beispiel #46
0
    def _generator(self):

        # container for LST data
        self.data = LSTDataContainer()
        self.data.meta['input_url'] = self.input_url
        self.data.meta['max_events'] = self.max_events


        # fill LST data from the CameraConfig table
        self.fill_lst_service_container_from_zfile()

        # Instrument information
        for tel_id in self.data.lst.tels_with_data:

            assert (tel_id == 0)  # only LST1 for the moment (id = 0)

            # optics info from standard optics.fits.gz file
            optics = OpticsDescription.from_name("LST")
            optics.tel_subtype = ''  # to correct bug in reading

            # camera info from LSTCam-[geometry_version].camgeom.fits.gz file
            geometry_version = 2
            camera = CameraGeometry.from_name("LSTCam", geometry_version)

            tel_descr = TelescopeDescription(optics, camera)

            self.n_camera_pixels = tel_descr.camera.n_pixels
            tels = {tel_id: tel_descr}

            # LSTs telescope position taken from MC from the moment
            tel_pos = {tel_id: [50., 50., 16] * u.m}


        subarray = SubarrayDescription("LST1 subarray")
        subarray.tels = tels
        subarray.positions = tel_pos

        self.data.inst.subarray = subarray

        # loop on events
        for count, event in enumerate(self.multi_file):

            self.data.count = count

            # fill specific LST event data
            self.fill_lst_event_container_from_zfile(event)

            # fill general R0 data
            self.fill_r0_container_from_zfile(event)
            yield self.data
Beispiel #47
0
 def __init__(self, obstime=None):
     if obstime is None:
         self.obstime = Time('2013-11-01T03:00')
     else:
         self.obstime = obstime
         
     self.magic_location = EarthLocation(lat=Angle("28°45′42.462″"),
                        lon=Angle("-17°53′26.525″"),
                        height=2199.4 * u.m)
     
     self.altaz = AltAz(location=self.magic_location, obstime=self.obstime)
     
     self.focal_length = 16.97*u.m # Maybe get from file?
     self.camera = CameraGeometry.from_name('MAGICCam')
Beispiel #48
0
def test_slicing():
    """ Check that we can slice a camera into a smaller one """
    geom = CameraGeometry.from_name("NectarCam")
    sliced1 = geom[100:200]

    assert len(sliced1.pix_x) == 100
    assert len(sliced1.pix_y) == 100
    assert len(sliced1.pix_area) == 100
    assert len(sliced1.pix_id) == 100

    sliced2 = geom[[5, 7, 8, 9, 10]]
    assert sliced2.pix_id[0] == 5
    assert sliced2.pix_id[1] == 7
    assert len(sliced2.pix_x) == 5
Beispiel #49
0
def test_dl1_charge_calib(example_subarray):
    camera = CameraGeometry.from_name("CHEC")
    n_pixels = 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 and create pulses
    time_offset = random.uniform(mid - 10, mid + 10, n_pixels)[:, np.newaxis]
    y = norm.pdf(x, time_offset, pulse_sigma).astype("float32")

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

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

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

    event = DataContainer()
    telid = list(example_subarray.tel.keys())[0]
    event.dl0.tel[telid].waveform = y

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

    event.calibration.tel[telid].dl1.time_shift = time_offset
    event.calibration.tel[telid].dl1.pedestal_offset = pedestal * n_samples
    event.calibration.tel[telid].dl1.absolute_factor = absolute
    event.calibration.tel[telid].dl1.relative_factor = relative

    # Test without need for timing corrections
    calibrator = CameraCalibrator(
        subarray=example_subarray,
        image_extractor=FullWaveformSum(subarray=example_subarray),
    )
    calibrator(event)
    np.testing.assert_allclose(event.dl1.tel[telid].image, 1, rtol=1e-5)
Beispiel #50
0
def test_tailcuts_clean_simple():
    geom = CameraGeometry.from_name("LSTCam")
    image = np.zeros_like(geom.pix_id, dtype=np.float64)

    num_pix = 40
    some_neighs = geom.neighbors[num_pix][0:3]  # pick 3 neighbors
    image[num_pix] = 5.0  # set a single image pixel
    image[some_neighs] = 3.0  # make some boundaries that are neighbors
    image[10] = 3.0  # a boundary that is not a neighbor

    mask = cleaning.tailcuts_clean(geom, image, picture_thresh=4.5, boundary_thresh=2.5)

    assert 10 not in geom.pix_id[mask]
    assert set(some_neighs).union({num_pix}) == set(geom.pix_id[mask])
    assert np.count_nonzero(mask) == 4
Beispiel #51
0
    def _generator(self):

        # container for NectarCAM data
        self.data = NectarCAMDataContainer()
        self.data.meta['input_url'] = self.input_url

        # fill data from the CameraConfig table
        self.fill_nectarcam_service_container_from_zfile()

        # Instrument information
        for tel_id in self.data.nectarcam.tels_with_data:
            assert (tel_id == 0)  # only one telescope for the moment (id = 0)

            # optics info from standard optics.fits.gz file
            optics = OpticsDescription.from_name("MST")
            optics.tel_subtype = ''  # to correct bug in reading

            # camera info from NectarCam-[geometry_version].camgeom.fits.gz file
            geometry_version = 2
            camera = CameraGeometry.from_name("NectarCam", geometry_version)

            tel_descr = TelescopeDescription(optics, camera)

            tel_descr.optics.tel_subtype = ''  # to correct bug in reading

            self.n_camera_pixels = tel_descr.camera.n_pixels
            tels = {tel_id: tel_descr}

            # LSTs telescope position
            tel_pos = {tel_id: [0., 0., 0] * u.m}

        self.subarray = SubarrayDescription("MST prototype subarray")
        self.subarray.tels = tels
        self.subarray.positions = tel_pos

        self.data.inst.subarray = self.subarray

        # loop on events
        for count, event in enumerate(self.multi_file):

            self.data.count = count

            # fill specific NectarCAM event data
            self.fill_nectarcam_event_container_from_zfile(event)

            # fill general R0 data
            self.fill_r0_container_from_zfile(event)
            yield self.data
Beispiel #52
0
def test_skewness():
    np.random.seed(42)

    geom = CameraGeometry.from_name('LSTCam')

    width = 0.03 * u.m
    length = 0.15 * u.m
    intensity = 2500

    xs = u.Quantity([0.5, 0.5, -0.5, -0.5], u.m)
    ys = u.Quantity([0.5, -0.5, 0.5, -0.5], u.m)
    psis = Angle([-90, -45, 0, 45, 90], unit='deg')
    skews = [0, 0.3, 0.6]

    for x, y, psi, skew in itertools.product(xs, ys, psis, skews):
        # make a toymodel shower model
        model = toymodel.SkewedGaussian(
            x=x, y=y,
            width=width,
            length=length,
            psi=psi,
            skewness=skew,
        )

        _, signal, _ = model.generate_image(
            geom, intensity=intensity, nsb_level_pe=5,
        )

        result = hillas_parameters(geom, signal)

        assert quantity_approx(result.x, x, rel=0.1)
        assert quantity_approx(result.y, y, rel=0.1)

        assert quantity_approx(result.width, width, rel=0.1)
        assert quantity_approx(result.length, length, rel=0.1)

        psi_same = result.psi.to_value(u.deg) == approx(psi.deg, abs=3)
        psi_opposite = abs(result.psi.to_value(u.deg) - psi.deg) == approx(180.0, abs=3)
        assert psi_same or psi_opposite

        # if we have delta the other way around, we get a negative sign for skewness
        # skewness is quite imprecise, maybe we could improve this somehow
        if psi_same:
            assert result.skewness == approx(skew, abs=0.3)
        else:
            assert result.skewness == approx(-skew, abs=0.3)

        assert signal.sum() == result.intensity
Beispiel #53
0
def test_apply_time_delta_cleaning():
    geom = CameraGeometry.from_name("LSTCam")
    pulse_time = np.zeros(geom.n_pixels, dtype=np.float)

    pixel = 40
    neighbours = geom.neighbors[pixel]
    pulse_time[neighbours] = 32.0
    pulse_time[pixel] = 30.0
    mask = pulse_time > 0

    # Test unchanged
    td_mask = cleaning.apply_time_delta_cleaning(
        geom,
        mask,
        pulse_time,
        min_number_neighbors=1,
        time_limit=5,
    )
    test_mask = mask.copy()
    assert (test_mask == td_mask).all()

    # Test time_limit
    noise_neighbour = neighbours[0]
    pulse_time[noise_neighbour] += 10
    td_mask = cleaning.apply_time_delta_cleaning(
        geom,
        mask,
        pulse_time,
        min_number_neighbors=1,
        time_limit=5,
    )
    test_mask = mask.copy()
    test_mask[noise_neighbour] = 0
    assert (test_mask == td_mask).all()

    # Test min_number_neighbours
    td_mask = cleaning.apply_time_delta_cleaning(
        geom,
        mask,
        pulse_time,
        min_number_neighbors=4,
        time_limit=5,
    )
    test_mask = mask.copy()
    test_mask[neighbours] = 0
    assert (test_mask == td_mask).all()
Beispiel #54
0
    def __init__(self):
        self.fig = plt.figure(1, figsize=(7, 7))
        self.ax = self.fig.add_subplot(111)

        # TODO Make this more flexible for lab setup

        self.required_pe = 100
        self.geom = CameraGeometry.from_name("CHEC")
        self.npix = len(self.geom.pix_id)
        self.total_scale = np.ones(self.npix)
        self.pixel_mask = np.ones(self.npix)
        self.camera_curve_center_x = 1
        self.camera_curve_center_y = 0
        self.camera_curve_radius = 1
        self.pixel_pos = np.load(
            "/Users/armstrongt/Software/CTA/CHECsoft/CHECAnalysis/targetpipe/targetpipe/io/checm_pixel_pos.npy"
        )
        self.pix_size = np.sqrt(self.geom.pix_area[0]).value
        self.fiducial_radius = 0.2
        self.fiducial_center = self.camera_curve_center_x + self.camera_curve_radius * np.cos(
            np.pi
        )  # This is a little confusing, is it going to be set up to change the position of the lightsource
        self.lightsource_distance = 1
        self.lightsource_x = 0
        self.lightsource_y = 0
        self.ang_dist_file = np.loadtxt(
            "/Users/armstrongt/Workspace/CTA/MCValidation/src/ang_dist_2.dat",
            unpack=True)
        theta_f = np.pi / 2 - np.arccos(
            self.fiducial_radius / self.lightsource_distance)
        # theta_ls = theta_f#self.lightsource_angle * np.pi / 180
        theta_p = np.arctan(self.pix_size / (2 * self.lightsource_distance))
        # self.lightsource_angle = theta_ls * 180 / np.pi
        self.lightsource_angle = max(self.ang_dist_file[0])
        theta_ls = self.lightsource_angle * np.pi / 180
        self.lightsource_sa = 2 * np.pi * (1 - np.cos(theta_ls))
        self.fiducial_sa = 2 * np.pi * (1 - np.cos(theta_f))
        self.fiducial_percent = self.fiducial_sa / self.lightsource_sa
        if self.fiducial_percent > 1: self.fiducial_percent = 1
        self.pix_sa = 2 * np.pi * (1 - np.cos(theta_p))
        self.pix_percent = self.pix_sa / self.lightsource_sa
        if self.pix_percent > 1: self.pix_percent = 1

        photons = self.set_illumination(self.required_pe)
        print(photons)
        print(self.lightsource_angle)
Beispiel #55
0
    def __init__(self, run_file_mask):
        """
        Constructor of the class. Defines the run to use and the camera pixel arrangement.

        Parameters
        ----------
        run_file_mask: str
            A path mask for files belonging to the run. Must correspond to a single run
            or an exception will be raised. Must correspond to calibrated ("sorcerer"-level)
            data.
        """

        self.run_file_mask = run_file_mask

        # Loading the camera geometry
        camera_geometry = CameraGeometry.from_name('MAGICCam')
        self.camera_pixel_x = camera_geometry.pix_x.value
        self.camera_pixel_y = camera_geometry.pix_y.value
        self.n_camera_pixels = len(self.camera_pixel_x)

        # Preparing the lists of M1/2 data files
        file_list = glob.glob(run_file_mask)
        self.m1_file_list = list(filter(lambda name: '_M1_' in name, file_list))
        self.m1_file_list.sort()
        self.m2_file_list = list(filter(lambda name: '_M2_' in name, file_list))
        self.m2_file_list.sort()

        # Retrieving the list of run numbers corresponding to the data files
        run_numbers = list(map(self._get_run_number, file_list))
        run_numbers = np.unique(run_numbers)

        # Checking if a single run is going to be read
        if len(run_numbers) > 1:
            raise ValueError("Run mask corresponds to more than one run: {}".format(run_numbers))

        # Reading the event data
        self.event_data = dict()
        self.event_data['M1'] = self.load_events(self.m1_file_list)
        self.event_data['M2'] = self.load_events(self.m2_file_list)

        # Detecting pedestal events
        self.pedestal_ids = self._find_pedestal_events()
        # Detecting stereo events
        self.stereo_ids = self._find_stereo_events()
        # Detecting mono events
        self.mono_ids = self._find_mono_events()
def test_ChaudhuriKunduRingFitter():

    geom = CameraGeometry.from_name('HESS-I')

    ring_rad = np.deg2rad(1. * u.deg) * 15.  # make sure this is in camera coordinates
    ring_width = np.deg2rad(0.05 * u.deg) * 15.
    geom_pixall = np.empty(geom.pix_x.shape + (2,))
    geom_pixall[..., 0] = geom.pix_x.value
    geom_pixall[..., 1] = geom.pix_y.value

    # image = generate_muon_model(geom_pixall, ring_rad, ring_width, 0.3, 0.2)
    muon_model = partial(toymodel.generate_muon_model, radius=ring_rad.value,
                         width=ring_width.value, centre_x=-0.2, centre_y=-0.3)

    toymodel_image, toy_signal, toy_noise = \
        toymodel.make_toymodel_shower_image(geom, muon_model)

    clean_toy_mask = tailcuts_clean(geom, toymodel_image,
                                    boundary_thresh=5, picture_thresh=10)

    muonring = muon_ring_finder.ChaudhuriKunduRingFitter(None)

    x = np.rad2deg((geom.pix_x.value / 15.) * u.rad)  # .value
    y = np.rad2deg((geom.pix_y.value / 15.) * u.rad)  # .value

    muonringparam = muonring.fit(x, y, toymodel_image * clean_toy_mask)

    dist = np.sqrt(np.power(x - muonringparam.ring_center_x, 2)
                   + np.power(y - muonringparam.ring_center_y, 2))
    ring_dist = np.abs(dist - muonringparam.ring_radius)
    muonringparam = muonring.fit(x, y, toymodel_image * (ring_dist <
                                                         muonringparam.ring_radius * 0.4))

    dist = np.sqrt(np.power(x - muonringparam.ring_center_x, 2) +
                   np.power(y - muonringparam.ring_center_y, 2))
    ring_dist = np.abs(dist - muonringparam.ring_radius)
    muonringparam = muonring.fit(x, y, toymodel_image * (ring_dist <
                                                         muonringparam.ring_radius * 0.4))

    print('Fitted ring radius', muonringparam.ring_radius, 'c.f.', ring_rad)
    print('Fitted ring centre', muonringparam.ring_center_x, muonringparam.ring_center_y)

    assert muonringparam.ring_radius is not ring_rad  # .value
    assert muonringparam.ring_center_x is not -0.2
    assert muonringparam.ring_center_y is not -0.3
Beispiel #57
0
def test_dilate():
    geom = CameraGeometry.from_name("LSTCam")
    mask = np.zeros_like(geom.pix_id, dtype=bool)

    mask[100] = True  # a single pixel far from a border is true.
    assert mask.sum() == 1

    # dilate a single row
    dmask = cleaning.dilate(geom, mask)
    assert dmask.sum() == 1 + 6

    # dilate a second row
    dmask = cleaning.dilate(geom, dmask)
    assert dmask.sum() == 1 + 6 + 12

    # dilate a third row
    dmask = cleaning.dilate(geom, dmask)
    assert dmask.sum() == 1 + 6 + 12 + 18
Beispiel #58
0
def test_tailcuts_clean_simple():
    geom = CameraGeometry.from_name("LSTCam")
    image = np.zeros_like(geom.pix_id, dtype=np.float)

    num_pix = 40
    some_neighs = geom.neighbors[num_pix][0:3]  # pick 4 neighbors
    image[num_pix] = 5.0  # set a single image pixel
    image[some_neighs] = 3.0  # make some boundaries that are neighbors
    image[10] = 3.0  # a boundary that is not a neighbor

    mask = cleaning.tailcuts_clean(geom, image, picture_thresh=4.5,
                                   boundary_thresh=2.5)

    print((mask > 0).sum(), "clean pixels")
    print(geom.pix_id[mask])

    assert 10 not in geom.pix_id[mask]
    assert set(some_neighs).union({num_pix}) == set(geom.pix_id[mask])
    assert (mask > 0).sum() == 4
Beispiel #59
0
def test_neighbor_pixels(cam_id):
    """
    test if each camera has a reasonable number of neighbor pixels (4 for
    rectangular, and 6 for hexagonal.  Other than edge pixels, the majority
    should have the same value
    """

    geom = CameraGeometry.from_name(cam_id)
    n_pix = len(geom.pix_id)
    n_neighbors = [len(x) for x in geom.neighbors]

    if geom.pix_type.startswith('hex'):
        assert n_neighbors.count(6) > 0.5 * n_pix
        assert n_neighbors.count(6) > n_neighbors.count(4)

    if geom.pix_type.startswith('rect'):
        assert n_neighbors.count(4) > 0.5 * n_pix
        assert n_neighbors.count(5) == 0
        assert n_neighbors.count(6) == 0

    assert n_neighbors.count(1) == 0  # no pixel should have a single neighbor
Beispiel #60
0
def test_with_toy():
    np.random.seed(42)

    geom = CameraGeometry.from_name('LSTCam')

    width = 0.03 * u.m
    length = 0.15 * u.m
    intensity = 500

    xs = u.Quantity([0.5, 0.5, -0.5, -0.5], u.m)
    ys = u.Quantity([0.5, -0.5, 0.5, -0.5], u.m)
    psis = Angle([-90, -45, 0, 45, 90], unit='deg')

    for x, y in zip(xs, ys):
        for psi in psis:

            # make a toymodel shower model
            model = toymodel.Gaussian(
                x=x, y=y,
                width=width, length=length,
                psi=psi,
            )

            image, signal, noise = model.generate_image(
                geom, intensity=intensity, nsb_level_pe=5,
            )

            result = hillas_parameters(geom, signal)

            assert quantity_approx(result.x, x, rel=0.1)
            assert quantity_approx(result.y, y, rel=0.1)

            assert quantity_approx(result.width, width, rel=0.1)
            assert quantity_approx(result.length, length, rel=0.1)
            assert (
                (result.psi.to_value(u.deg) == approx(psi.deg, abs=2))
                or abs(result.psi.to_value(u.deg) - psi.deg) == approx(180.0, abs=2)
            )

            assert signal.sum() == result.intensity