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
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
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()
def test_calc_pixel_neighbors_square_diagonal(): x, y = np.meshgrid(np.arange(20), np.arange(20)) cam = CameraGeometry( cam_id='test', pix_id=np.arange(400), pix_type='rectangular', pix_x=u.Quantity(x.ravel(), u.cm), pix_y=u.Quantity(y.ravel(), u.cm), pix_area=u.Quantity(np.ones(400), u.cm**2), ) cam._neighbors = cam.calc_pixel_neighbors(diagonal=True) assert set(cam.neighbors[21]) == {0, 1, 2, 20, 22, 40, 41, 42}
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 display_event(event): """an extremely inefficient display. It creates new instances of CameraDisplay for every event and every camera, and also new axes for each event. It's hacked, but it works """ print("Displaying... please wait (this is an inefficient implementation)") global fig ntels = len(event.r0.tels_with_data) fig.clear() plt.suptitle("EVENT {}".format(event.r0.event_id)) disps = [] for ii, tel_id in enumerate(event.r0.tels_with_data): print("\t draw cam {}...".format(tel_id)) nn = int(ceil(sqrt(ntels))) ax = plt.subplot(nn, nn, ii + 1) x, y = event.inst.pixel_pos[tel_id] geom = CameraGeometry.guess(x, y, event.inst.optical_foclen[tel_id]) disp = CameraDisplay(geom, ax=ax, title="CT{0}".format(tel_id)) disp.pixels.set_antialiaseds(False) disp.autoupdate = False disp.cmap = random.choice(cmaps) chan = 0 signals = event.r0.tel[tel_id].adc_sums[chan].astype(float) signals -= signals.mean() disp.image = signals disp.set_limits_percent(95) disp.add_colorbar() disps.append(disp) return disps
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
def test_precal_neighbors(): """ test that pre-calculated neighbor lists don't get overwritten by automatic ones """ geom = CameraGeometry(camera_name="TestCam", pix_id=np.arange(3), pix_x=np.arange(3) * u.deg, pix_y=np.arange(3) * u.deg, pix_area=np.ones(3) * u.deg**2, neighbors=[[ 1, ], [0, 2], [ 1, ]], pix_type='rectangular', pix_rotation="0deg", cam_rotation="0deg") neigh = geom.neighbors assert len(neigh) == len(geom.pix_x) nmat = geom.neighbor_matrix assert nmat.shape == (len(geom.pix_x), len(geom.pix_x)) assert np.all(nmat.T == nmat)
def test_number_of_islands(): from ctapipe.image import number_of_islands # test with LST geometry (1855 pixels) geom = CameraGeometry.from_name("LSTCam") # create 18 triggered pixels grouped to 5 clusters mask = np.zeros(geom.n_pixels).astype("bool") triggered_pixels = np.array( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 37, 38, 111, 222]) mask[triggered_pixels] = True island_labels_true = np.zeros(geom.n_pixels, dtype=np.int16) island_labels_true[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]] = 1 island_labels_true[14] = 2 island_labels_true[[37, 38]] = 3 island_labels_true[111] = 4 island_labels_true[222] = 5 n_islands, island_labels = number_of_islands(geom, mask) n_islands_true = 5 # non cleaning pixels should be zero assert np.all(island_labels[~mask] == 0) # all other should have some label assert np.all(island_labels[mask] > 0) assert n_islands == n_islands_true assert_allclose(island_labels, island_labels_true) assert island_labels.dtype == np.int16
def get_camera(self, tel_id): if not tel_id in self.camera_geom_dict: pos = self.inst.pixel_pos[tel_id] foclen = self.inst.optical_foclen[tel_id] geom = CameraGeometry.guess(*pos, foclen, apply_derotation=False) self.camera_geom_dict[tel_id] = geom return self.camera_geom_dict[tel_id]
def test_straight_line_width_0(): """ Test that hillas_parameters.width is 0 for a straight line of pixels """ # three pixels in a straight line long = np.array([0, 1, 2]) * 0.01 trans = np.zeros(len(long)) pix_id = np.arange(len(long)) rng = np.random.default_rng(0) for dx in (-1, 0, 1): for dy in (-1, 0, 1): for psi in np.linspace(0, np.pi, 20): x = dx + np.cos(psi) * long + np.sin(psi) * trans y = dy - np.sin(psi) * long + np.cos(psi) * trans geom = CameraGeometry( camera_name="testcam", pix_id=pix_id, pix_x=x * u.m, pix_y=y * u.m, pix_type="hexagonal", pix_area=1 * u.m**2, ) img = rng.poisson(5, size=len(long)) result = hillas_parameters(geom, img) assert result.width.value == 0 assert np.isnan(result.width_uncertainty.value)
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, ): 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. rng = np.random.default_rng(0) image, _, _ = model.generate_image(geom, intensity=1500, nsb_level_pe=3, rng=rng) # calculate pixels likely containing signal clean_mask = tailcuts_clean(geom, image, 10, 5) return geom, image, clean_mask
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
def test_waveform_model(): from ctapipe.image.toymodel import Gaussian geom = CameraGeometry.from_name("CHEC") readout = CameraReadout.from_name("CHEC") ref_duration = 67 n_ref_samples = 100 pulse_sigma = 3 ref_x_norm = np.linspace(0, ref_duration, n_ref_samples) ref_y_norm = norm.pdf(ref_x_norm, ref_duration / 2, pulse_sigma) readout.reference_pulse_shape = ref_y_norm[np.newaxis, :] readout.reference_pulse_sample_width = u.Quantity( ref_x_norm[1] - ref_x_norm[0], u.ns) readout.sampling_rate = u.Quantity(2, u.GHz) centroid_x = u.Quantity(0.05, u.m) centroid_y = u.Quantity(0.05, u.m) length = u.Quantity(0.03, u.m) width = u.Quantity(0.008, u.m) psi = u.Quantity(70, u.deg) time_gradient = u.Quantity(50, u.ns / u.m) time_intercept = u.Quantity(20, u.ns) _, charge, _ = Gaussian(x=centroid_x, y=centroid_y, width=width, length=length, psi=psi).generate_image(geom, 10000) time = obtain_time_image( geom.pix_x, geom.pix_y, centroid_x, centroid_y, psi, time_gradient, time_intercept, ) time[charge == 0] = 0 waveform_model = WaveformModel.from_camera_readout(readout) waveform = waveform_model.get_waveform(charge, time, 96) np.testing.assert_allclose(waveform.sum(axis=1), charge, rtol=1e-3) np.testing.assert_allclose(waveform.argmax(axis=1) / readout.sampling_rate.to_value(u.GHz), time, rtol=1e-1) time_2 = time + 1 time_2[charge == 0] = 0 waveform_2 = waveform_model.get_waveform(charge, time_2, 96) np.testing.assert_allclose(waveform_2.sum(axis=1), charge, rtol=1e-3) np.testing.assert_allclose( waveform_2.argmax(axis=1) / readout.sampling_rate.to_value(u.GHz), time_2, rtol=1e-1, ) assert (waveform_2.argmax(axis=1)[charge != 0] > waveform.argmax(axis=1)[charge != 0]).all()
def test_MuonRingFitter(method): """test MuonRingFitter""" # flashCam example center_xs = 0.3 * u.m center_ys = 0.6 * u.m radius = 0.3 * u.m width = 0.05 * u.m muon_model = toymodel.RingGaussian( x=center_xs, y=center_ys, radius=radius, sigma=width, ) # testing with flashcam geom = CameraGeometry.from_name("FlashCam") charge, _, _ = muon_model.generate_image(geom, intensity=1000, nsb_level_pe=5,) survivors = tailcuts_clean(geom, charge, 10, 12) muonfit = MuonRingFitter(fit_method=method) fit_result = muonfit(geom.pix_x, geom.pix_y, charge, survivors) print(fit_result) print(center_xs, center_ys, radius) assert u.isclose(fit_result.center_x, center_xs, 5e-2) assert u.isclose(fit_result.center_y, center_ys, 5e-2) assert u.isclose(fit_result.radius, radius, 5e-2)
def __init__(self): self.fig = plt.figure(1, figsize=(7, 7)) self.ax = self.fig.add_subplot(111) self.geom = CameraGeometry.from_name("CHEC") print(self.geom.pix_area) 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 = 0.006125 self.fiducial_radius = 0.2 self.fiducial_center = self.camera_curve_center_x + self.camera_curve_radius * np.cos( np.pi) self.lightsource_distance = 1 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_f * 180 / np.pi 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(2) print(photons) print(self.lightsource_angle)
def make_camera_binary_image(image, sigma, clean_bound, death_pixel_ids_list): fig, ax = plt.subplots(1, 2, figsize=(14, 7)) geom = CameraGeometry.from_name('LSTCam-003') disp0 = CameraDisplay(geom, ax=ax[0]) disp0.image = image disp0.cmap = plt.cm.gnuplot2 disp0.add_colorbar(ax=ax[0]) ax[0].set_title( "Cleaning threshold from interleaved pedestal. \n sigma = {}".format( sigma), fontsize=15) disp1 = CameraDisplay(geom, ax=ax[1]) disp1.image = image cmap = matplotlib.colors.ListedColormap(['black', 'red']) bounds = [0, clean_bound, 2 * clean_bound] norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N) disp1.cmap = cmap disp1.add_colorbar(norm=norm, boundaries=bounds, ticks=[0, clean_bound, 2 * clean_bound]) disp1.set_limits_minmax(0, 2 * clean_bound) disp1.highlight_pixels(death_pixel_ids_list, linewidth=3) ax[1].set_title("Red pixels - above cleaning tailcut threshold", fontsize=15) plt.tight_layout() plt.show()
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)
def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" kwargs = dict(config=self.config, tool=self) arrays = np.load(self.input_path) self.charge = self.dead.mask2d(arrays['charge']) self.charge = np.ma.masked_where(self.charge <= 0, self.charge) self.charge_error = np.ma.array(arrays['charge_error'], mask=self.charge.mask) self.hv = arrays['rundesc'] self.n_hv, self.n_pixels = self.charge.shape assert (self.n_hv == self.hv.size) geom = CameraGeometry.guess(*checm_pixel_pos * u.m, optical_foclen * u.m) self.modules = np.arange(self.n_pixels) // self.n_tmpix self.tmpix = np.arange(self.n_pixels) % self.n_tmpix self.n_tm = np.unique(self.modules).size # Init Plots self.p_camera_pix = Camera(self, "Gain Matching Pixels", geom) self.p_camera_tm = Camera(self, "Gain Matching TMs", geom) self.p_plotter_pix = Plotter(**kwargs) self.p_plotter_tm = Plotter(**kwargs)
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)
def setup_geom(self): self.geom = CameraGeometry.from_name(self.camera) self.npix = len(self.geom.pix_id) self.total_scale = np.ones(self.npix) self.pixel_mask = np.ones(self.npix) # pixfile = np.loadtxt("/Users/armstrongt/Workspace/CTA/MCValidation/src/MCValidation/configs/checs_pixel_mapping_fixedgainvar_justpix.dat", unpack=True) # self.geom.pix_x = pixfile[2]/100*u.m # self.geom.pix_y = pixfile[3]/100*u.m # self.geom.pix_id = pixfile[0] # self.geom.pix_size = 0.623/100*u.m # print(self.geom) self.pix_size = np.sqrt(self.geom.pix_area[0]).value 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.ang_dist_file = np.loadtxt(self.ang_dist_file_string, 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
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_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]
def test_straight_line_width_0(): ''' Test that hillas_parameters.width is 0 for a straight line of pixels ''' # three pixels in a straight line long = np.array([0, 1, 2]) * 0.01 trans = np.zeros(len(long)) pix_id = np.arange(len(long)) np.random.seed(0) for dx in (-1, 0, 1): for dy in (-1, 0, 1): for psi in np.linspace(0, np.pi, 20): x = dx + np.cos(psi) * long + np.sin(psi) * trans y = dy - np.sin(psi) * long + np.cos(psi) * trans geom = CameraGeometry( camera_name='testcam', pix_id=pix_id, pix_x=x * u.m, pix_y=y * u.m, pix_type='hexagonal', pix_area=1 * u.m**2, ) img = np.random.poisson(5, size=len(long)) result = hillas_parameters(geom, img) assert result.width.value == 0
def test_picker(): from ctapipe.visualization import CameraDisplay from matplotlib.backend_bases import MouseEvent, MouseButton geom = CameraGeometry.from_name("LSTCam") clicked_pixels = [] class PickingCameraDisplay(CameraDisplay): def on_pixel_clicked(self, pix_id): print(f"YOU CLICKED PIXEL {pix_id}") clicked_pixels.append(pix_id) fig = plt.figure(figsize=(10, 10), dpi=100) ax = fig.add_axes([0, 0, 1, 1]) disp = PickingCameraDisplay(geom, ax=ax) disp.enable_pixel_picker() fig.canvas.draw() # emulate someone clicking the central pixel event = MouseEvent("button_press_event", fig.canvas, x=500, y=500, button=MouseButton.LEFT) disp.pixels.pick(event) assert len(clicked_pixels) > 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 ) 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)
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
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)
def build_camera_geometry(cam_settings, telescope): pixel_shape = cam_settings['pixel_shape'][0] try: pix_type, pix_rotation = CameraGeometry.simtel_shape_to_type(pixel_shape) except ValueError: warnings.warn( f'Unkown pixel_shape {pixel_shape} for camera_type {telescope.camera_name}', UnknownPixelShapeWarning, ) pix_type = 'hexagon' pix_rotation = '0d' camera = CameraGeometry( telescope.camera_name, pix_id=np.arange(cam_settings['n_pixels']), pix_x=u.Quantity(cam_settings['pixel_x'], u.m), pix_y=u.Quantity(cam_settings['pixel_y'], u.m), pix_area=u.Quantity(cam_settings['pixel_area'], u.m**2), pix_type=pix_type, pix_rotation=pix_rotation, cam_rotation=-Angle(cam_settings['cam_rot'], u.rad), apply_derotation=True, ) return camera
def test_tailcuts_clean_min_neighbors_2(): """ requiring that picture pixels have at least two neighbors above picture_thresh""" # start with simple 3-pixel camera geom = CameraGeometry.make_rectangular(3, 1, (-1, 1)) p = 15 # picture value b = 7 # boundary value testcases = { (p, p, 0): [False, False, False], (p, 0, p): [False, False, False], (p, b, p): [False, False, False], (p, b, 0): [False, False, False], (b, b, 0): [False, False, False], (p, p, p): [True, True, True], } for image, mask in testcases.items(): result = cleaning.tailcuts_clean( geom, np.array(image), picture_thresh=15, boundary_thresh=5, min_number_picture_neighbors=2, keep_isolated_pixels=False, ) assert (result == mask).all()
def test_tailcuts_clean_with_isolated_pixels(): # start with simple 3-pixel camera geom = CameraGeometry.make_rectangular(3, 1, (-1, 1)) p = 15 # picture value b = 7 # boundary value testcases = { (p, p, 0): [True, True, False], (p, 0, p): [True, False, True], (p, b, p): [True, True, True], (p, b, 0): [True, True, False], (0, p, 0): [False, True, False], (b, b, 0): [False, False, False], } for image, mask in testcases.items(): result = cleaning.tailcuts_clean( geom, np.array(image), picture_thresh=15, boundary_thresh=5, keep_isolated_pixels=True, ) assert (result == mask).all()
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
def test_camera_coordinate_transform(camera_name): """test conversion of the coordinates stored in a camera frame""" from ctapipe.coordinates import EngineeringCameraFrame, CameraFrame, TelescopeFrame 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)) # also test converting into a spherical frame: focal_length = 1.2 * u.m geom.frame = CameraFrame(focal_length=focal_length) telescope_frame = TelescopeFrame() sky_geom = geom.transform_to(telescope_frame) x = sky_geom.pix_x.to_value(u.deg) assert len(x) == len(geom.pix_x) # and test going backward from spherical to cartesian: geom_cam = sky_geom.transform_to(CameraFrame(focal_length=focal_length)) assert np.allclose(geom_cam.pix_x.to_value(unit), geom.pix_x.to_value(unit))
def test_FitGammaHillas(): ''' a test of the complete fit procedure on one event including: • tailcut cleaning • hillas parametrisation • GreatCircle creation • direction fit • position fit in the end, proper units in the output are asserted ''' filename = get_dataset("gamma_test.simtel.gz") fit = HillasReconstructor() cam_geom = {} tel_phi = {} tel_theta = {} source = hessio_event_source(filename) for event in source: hillas_dict = {} for tel_id in event.dl0.tels_with_data: if tel_id not in cam_geom: cam_geom[tel_id] = CameraGeometry.guess( event.inst.pixel_pos[tel_id][0], event.inst.pixel_pos[tel_id][1], event.inst.optical_foclen[tel_id]) tel_phi[tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad tel_theta[tel_id] = (np.pi/2-event.mc.tel[tel_id].altitude_raw)*u.rad pmt_signal = event.r0.tel[tel_id].adc_sums[0] mask = tailcuts_clean(cam_geom[tel_id], pmt_signal, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask == 0] = 0 try: moments = hillas_parameters(event.inst.pixel_pos[tel_id][0], event.inst.pixel_pos[tel_id][1], pmt_signal) hillas_dict[tel_id] = moments except HillasParameterizationError as e: print(e) continue if len(hillas_dict) < 2: continue fit_result = fit.predict(hillas_dict, event.inst, tel_phi, tel_theta) print(fit_result) fit_result.alt.to(u.deg) fit_result.az.to(u.deg) fit_result.core_x.to(u.m) assert fit_result.is_valid return
def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" kwargs = dict(config=self.config, tool=self) arrays = np.load(self.input_path) self.charge = self.dead.mask2d(arrays['charge']) self.charge_error = self.dead.mask2d(arrays['charge_error']) self.rundesc = arrays['rundesc'] self.n_run, self.n_pixels = self.charge.shape assert (self.n_run == self.rundesc.size) geom = CameraGeometry.guess(*checm_pixel_pos * u.m, optical_foclen * u.m) self.modules = np.arange(self.n_pixels) // self.n_tmpix self.tmpix = np.arange(self.n_pixels) % self.n_tmpix self.n_tm = np.unique(self.modules).size # Init Plots self.p_c_pix = Camera(self, "", geom) self.p_c_tm = Camera(self, "", geom) self.p_c_tmpixspread = Camera(self, "", geom) self.p_p_pix = Plotter(**kwargs) self.p_p_tm = Plotter(**kwargs) self.p_b_tmpixspread = BoxPlotter(**kwargs) self.p_b_tmspread = BoxPlotter(**kwargs) self.p_b_pixspread = BoxPlotter(**kwargs)
def test_border_pixels(): """ check we can find 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_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
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.05, length=0.15, psi=psi, ) # generate toymodel image in camera for this shower model. image, signal, noise = toymodel.make_toymodel_shower_image( geom, model.pdf, intensity=1500, nsb_level_pe=3, ) # denoise the image, so we can calculate hillas params clean_mask = tailcuts_clean(geom, image, 10, 5) return geom, image, clean_mask
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 = 200 psi = "30d" # make a toymodel shower model model = Gaussian(x=x, y=y, width=width, length=length, psi=psi) _, signal, _ = 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, _ = 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)
def test_neighbor_pixels(camera_name): """ 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(camera_name) n_pix = len(geom.pix_id) n_neighbors = [len(x) for x in geom.neighbors] if geom.pix_type == PixelShape.HEXAGON: assert n_neighbors.count(6) > 0.5 * n_pix assert n_neighbors.count(6) > n_neighbors.count(4) if geom.pix_type == PixelShape.SQUARE: 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 camera_name != "Whipple490": assert np.all(geom.neighbor_matrix == geom.neighbor_matrix.T) assert n_neighbors.count( 1) == 0 # no pixel should have a single neighbor
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)
def test_tailcuts_clean_min_neighbors_1(): """ requiring that picture pixels have at least one neighbor above picture_thres: """ # start with simple 3-pixel camera geom = CameraGeometry.make_rectangular(3, 1, (-1, 1)) p = 15 # picture value b = 7 # boundary value testcases = {(p, p, 0): [True, True, False], (p, 0, p): [False, False, False], (p, b, p): [False, False, False], (p, b, 0): [False, False, False], (b, b, 0): [False, False, False], (0, p, 0): [False, False, False], (p, p, p): [True, True, True]} for image, mask in testcases.items(): result = cleaning.tailcuts_clean(geom, np.array(image), picture_thresh=15, boundary_thresh=5, min_number_picture_neighbors=1, keep_isolated_pixels=False) assert (result == mask).all()
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)
def test_camera_display_single(): """ test CameraDisplay functionality """ from ..mpl_camera 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 = 'nipy_spectral' disp.set_limits_minmax(0, 10) disp.set_limits_percent(95) disp.enable_pixel_picker() disp.highlight_pixels([1, 2, 3, 4, 5]) disp.norm = 'log' disp.norm = 'symlog' disp.cmap = 'rainbow' with pytest.raises(ValueError): disp.image = ones(10) with pytest.raises(ValueError): disp.add_colorbar() disp.add_ellipse(centroid=(0, 0), width=0.1, length=0.1, angle=0.1) disp.clear_overlays()
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
def display_telescope(calibrated_data,cam,tel_id,pdffilename): logger.info("Tel_ID %d\n"%tel_id) pp = PdfPages("%s"%pdffilename) global fig for event in calibrated_data: tels = list(event.r0.tels_with_data) logger.debug(tels) # Select telescope if tel_id not in tels: continue fig.clear() # geom = cam['CameraTable_VersionFeb2016_TelID%s'%tel_id] geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id], event.inst.optical_foclen[tel_id]) # Select number of pads to display. It depends on the numberr of gains: nchan = event.inst.num_channels[tel_id] plt.suptitle("EVENT {} {:.1e} TeV @({:.1f},{:.1f})deg @{:.1f} m".format( event.r0.event_id, event.mc.energy, event.mc.alt, event.mc.az, np.sqrt(pow(event.mc.core_x, 2) + pow(event.mc.core_y, 2)))) print("\t draw cam {} (gains={})...".format(tel_id,nchan)) ax=[] disp=[] signals=[] npads=0 for i in range(nchan): npads += 1 # Display the camera charge (HG/LG) ax.append(plt.subplot(nchan, 2, npads)) disp.append(visualization.CameraDisplay(geom, ax=ax[-1], title="CT{} [{} ADC cts]".format(tel_id,gain_label[i]))) disp[-1].pixels.set_antialiaseds(False) signals.append(event.r0.tel[tel_id].adc_sums[i]) disp[-1].image = signals[-1] disp[-1].pixels.set_cmap(get_cmap(disp[-1].image)) disp[-1].add_colorbar(label=" [{} ADC cts]".format(gain_label[i])) # Display the camera charge for significant pixels (HG/LG) npads += 1 ax.append(plt.subplot(nchan, 2, npads)) disp.append(visualization.CameraDisplay(geom, ax=ax[-1], title="CT{} [{} ADC cts]".format(tel_id,gain_label[i]))) disp[-1].pixels.set_antialiaseds(False) signals.append(event.r0.tel[tel_id].adc_sums[i]) m = (get_zero_sup_mode(tel_id) & 0x001) or (get_significant(tel_id) & 0x020) disp[-1].image = signals[-1]*(m/m.max()) disp[-1].pixels.set_cmap(get_cmap(disp[-1].image)) disp[-1].add_colorbar(label=" [{} ADC cts]".format(gain_label[i])) plt.pause(0.1) pp.savefig(fig) pp.close()
def get_geometry(self, tel): npix = len(self.event.r0.tel[tel].adc_sums[0]) cam_dimensions = (npix, self.event.inst.optical_foclen[tel]) if tel not in self.geom_dict: self.geom_dict[tel] = \ CameraGeometry.guess(*self.event.inst.pixel_pos[tel], self.event.inst.optical_foclen[tel]) return self.geom_dict[tel]
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()
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
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, )
def _build_telescope_description(self, file, tel_id): pix_x, pix_y = u.Quantity(file.get_pixel_position(tel_id), u.m) focal_length = u.Quantity(file.get_optical_foclen(tel_id), u.m) n_pixels = len(pix_x) try: telescope = guess_telescope(n_pixels, focal_length) except ValueError: telescope = UNKNOWN_TELESCOPE pixel_shape = file.get_pixel_shape(tel_id)[0] try: pix_type, pix_rot = CameraGeometry.simtel_shape_to_type(pixel_shape) except ValueError: warnings.warn( f'Unkown pixel_shape {pixel_shape} for tel_id {tel_id}', UnknownPixelShapeWarning, ) pix_type = 'hexagon' pix_rot = '0d' pix_area = u.Quantity(file.get_pixel_area(tel_id), u.m**2) mirror_area = u.Quantity(file.get_mirror_area(tel_id), u.m**2) num_tiles = file.get_mirror_number(tel_id) cam_rot = file.get_camera_rotation_angle(tel_id) num_mirrors = file.get_mirror_number(tel_id) camera = CameraGeometry( telescope.camera_name, pix_id=np.arange(n_pixels), pix_x=pix_x, pix_y=pix_y, pix_area=pix_area, pix_type=pix_type, pix_rotation=pix_rot, cam_rotation=-Angle(cam_rot, u.rad), apply_derotation=True, ) optics = OpticsDescription( name=telescope.name, num_mirrors=num_mirrors, equivalent_focal_length=focal_length, mirror_area=mirror_area, num_mirror_tiles=num_tiles, ) return TelescopeDescription( name=telescope.name, type=telescope.type, camera=camera, optics=optics, )
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
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
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