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=rot) 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) plt.tight_layout() plt.pause(.1) assert np.abs(hillas_1.phi - hillas_0.phi).deg < 1.0
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_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 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 test_hillas_container(): geom, image = create_sample_image_zeros(psi="0d") params = hillas_parameters(geom, image) assert isinstance(params, CameraHillasParametersContainer) geom.frame = CameraFrame(focal_length=28 * u.m) geom_telescope_frame = geom.transform_to(TelescopeFrame()) params = hillas_parameters(geom_telescope_frame, image) assert isinstance(params, HillasParametersContainer)
def test_hillas_masked_array(): geom, image, clean_mask = create_sample_image(psi='0d') image_zeros = image.copy() image_zeros[~clean_mask] = 0 hillas_zeros = hillas_parameters(geom, image_zeros) image_masked = np.ma.masked_array(image, mask=~clean_mask) hillas_masked = hillas_parameters(geom, image_masked) compare_hillas(hillas_zeros, hillas_masked)
def test_hillas_selected(): """ test Hillas-parameter routines on a sample image with selected values against a sample image with masked values set tozero """ geom, image = create_sample_image_zeros() geom_selected, image_selected = create_sample_image_selected_pixel() results = hillas_parameters(geom, image) results_selected = hillas_parameters(geom_selected, image_selected) compare_hillas(results, results_selected)
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
def test_array_draw(): filename = get_dataset("gamma_test.simtel.gz") cam_geom = {} source = hessio_event_source(filename, max_events=2) r1 = HESSIOR1Calibrator() dl0 = CameraDL0Reducer() calibrator = CameraDL1Calibrator() for event in source: array_pointing = SkyCoord( event.mcheader.run_array_direction[1] * u.rad, event.mcheader.run_array_direction[0] * u.rad, frame=AltAz) # array_view = ArrayPlotter(instrument=event.inst, # system=TiltedGroundFrame( # pointing_direction=array_pointing)) hillas_dict = {} r1.calibrate(event) dl0.reduce(event) calibrator.calibrate(event) # calibrate the events # store MC pointing direction for the array for tel_id in event.dl0.tels_with_data: pmt_signal = event.dl1.tel[tel_id].image[0] geom = deepcopy(event.inst.subarray.tel[tel_id].camera) fl = event.inst.subarray.tel[tel_id].optics.equivalent_focal_length # Transform the pixels positions into nominal coordinates camera_coord = CameraFrame(x=geom.pix_x, y=geom.pix_y, z=np.zeros(geom.pix_x.shape) * u.m, focal_length=fl, rotation=90 * u.deg - geom.cam_rotation) nom_coord = camera_coord.transform_to( NominalFrame(array_direction=array_pointing, pointing_direction=array_pointing)) geom.pix_x = nom_coord.x geom.pix_y = nom_coord.y mask = tailcuts_clean(geom, pmt_signal, picture_thresh=10., boundary_thresh=5.) try: moments = hillas_parameters(geom, pmt_signal * mask) hillas_dict[tel_id] = moments nom_coord = NominalPlotter(hillas_parameters=hillas_dict, draw_axes=True) nom_coord.draw_array() except HillasParameterizationError as e: print(e) continue
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 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 hillas(event): hillas_dict = {} tel_phi = {} tel_theta = {} for tel in event: tel_id = tel['tel_id'] tel_phi[tel_id] = 0. * u.deg tel_theta[tel_id] = 20. * u.deg pmt_signal = tel['adc_sums'][0] # print(pmt_signal) inst = broadcastInst.value pix_x = inst.pixel_pos[tel_id][0] pix_y = inst.pixel_pos[tel_id][1] foc = inst.optical_foclen[tel_id] cam_geom = CameraGeometry.guess(pix_x, pix_y, foc) mask = tailcuts_clean(cam_geom, pmt_signal, 1, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask == 0] = 0 try: moments = hillas_parameters(cam_geom.pix_x, cam_geom.pix_y, pmt_signal) hillas_dict[tel['tel_id']] = moments except HillasParameterizationError as e: print(e) return (hillas_dict, tel_phi, tel_theta)
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 draw_several_cams(geom, ncams=4): cmaps = ['jet', 'afmhot', 'terrain', 'autumn'] fig, axs = plt.subplots(1, ncams, figsize=(15, 4), sharey=True, sharex=True) for ii in range(ncams): disp = visualization.CameraDisplay( geom, ax=axs[ii], title="CT{}".format(ii + 1), ) disp.cmap = cmaps[ii] model = toymodel.generate_2d_shower_model( centroid=(0.2 - ii * 0.1, -ii * 0.05), width=0.005 + 0.001 * ii, length=0.1 + 0.05 * ii, psi=ii * 20 * u.deg, ) image, sig, bg = toymodel.make_toymodel_shower_image( geom, model.pdf, intensity=50, nsb_level_pe=1000, ) clean = image.copy() clean[image <= 3.0 * image.mean()] = 0.0 hillas = hillas_parameters(geom.pix_x, geom.pix_y, clean) disp.image = image disp.add_colorbar(ax=axs[ii]) disp.set_limits_percent(95) disp.overlay_moments(hillas, linewidth=3, color='blue')
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_path("gamma_test.simtel.gz") fit = FitGammaHillas() 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] = 0.*u.deg tel_theta[tel_id] = 20.*u.deg pmt_signal = event.dl0.tel[tel_id].adc_sums[0] mask = tailcuts_clean(cam_geom[tel_id], pmt_signal, 1, 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 main(): paths = [ "/Volumes/gct-jason/astri_onsky_archive/d2019-05-15_simulations/proton/run1_dl1.h5", ] df_list = [] for ipath, path in enumerate(paths): with DL1Reader(path) as reader: n_events = reader.get_metadata()['n_events'] mapping = reader.get_mapping() geom = get_ctapipe_camera_geometry(mapping, plate_scale=37.56e-3) desc = "Looping over events" it = reader.iterate_over_events() for df in tqdm(it, total=n_events, desc=desc): iev = df['iev'].values[0] image = df['photons'].values time = df['pulse_time'].values mask = obtain_cleaning_mask(geom, image, time) if not mask.any(): continue image_m = image[mask] time_m = time[mask] geom_m = geom[mask] try: hillas = hillas_parameters(geom_m, image_m) except HillasParameterizationError: continue # timing_parameters(geom_m, image_m, time_m, hillas) gt0 = image_m > 0 pix_x = geom_m.pix_x[gt0] pix_y = geom_m.pix_y[gt0] peakpos = time_m[gt0] intensity = image_m[gt0] longi, trans = camera_to_shower_coordinates( pix_x, pix_y, hillas.x, hillas.y, hillas.psi) longi = longi.value trans = trans.value # df_list.append(pd.DataFrame(dict( # ipath=ipath, # iev=iev, # longi=longi, # peakpos=peakpos, # ))) p_relation = RelationPlotter() p_relation.plot(longi, peakpos, intensity) p_relation.save( get_plot( f"d190524_time_gradient/relation/i{ipath}_e{iev}.pdf"))
def test_reconstruction(): """ a test of the complete fit procedure on one event including: • tailcut cleaning • hillas parametrisation • HillasPlane creation • direction fit • position fit in the end, proper units in the output are asserted """ filename = get_dataset_path("gamma_test.simtel.gz") fit = HillasReconstructor() tel_azimuth = {} tel_altitude = {} source = EventSourceFactory.produce( input_url=filename, product='HESSIOEventSource', ) for event in source: hillas_dict = {} for tel_id in event.dl0.tels_with_data: geom = event.inst.subarray.tel[tel_id].camera tel_azimuth[tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad tel_altitude[tel_id] = event.mc.tel[tel_id].altitude_raw * u.rad pmt_signal = event.r0.tel[tel_id].image[0] mask = tailcuts_clean(geom, pmt_signal, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask == 0] = 0 try: moments = hillas_parameters(geom, 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_azimuth, tel_altitude) 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 test_width_0(): geom, image, clean_mask = create_sample_image("30d") hillas = hillas_parameters(geom[clean_mask], image[clean_mask]) hillas.width = 0 * u.m conc = concentration_parameters(geom, image, hillas) assert conc.core == 0
def test_array_draw(): filename = get_dataset("gamma_test.simtel.gz") cam_geom = {} source = hessio_event_source(filename, max_events=2) r1 = HessioR1Calibrator(None, None) dl0 = CameraDL0Reducer(None, None) calibrator = CameraDL1Calibrator(None, None) for event in source: array_pointing = SkyCoord(event.mcheader.run_array_direction[1] * u.rad, event.mcheader.run_array_direction[0] * u.rad, frame=AltAz) # array_view = ArrayPlotter(instrument=event.inst, # system=TiltedGroundFrame( # pointing_direction=array_pointing)) hillas_dict = {} r1.calibrate(event) dl0.reduce(event) calibrator.calibrate(event) # calibrate the events # store MC pointing direction for the array for tel_id in event.dl0.tels_with_data: pmt_signal = event.dl1.tel[tel_id].image[0] geom = event.inst.subarray.tel[tel_id].camera fl = event.inst.subarray.tel[tel_id].optics.effective_focal_length # Transform the pixels positions into nominal coordinates camera_coord = CameraFrame(x=geom.pix_x, y=geom.pix_y, z=np.zeros(geom.pix_x.shape) * u.m, focal_length=fl, rotation=90 * u.deg - geom.cam_rotation) nom_coord = camera_coord.transform_to( NominalFrame(array_direction=array_pointing, pointing_direction=array_pointing)) mask = tailcuts_clean(geom, pmt_signal, picture_thresh=10., boundary_thresh=5.) try: moments = hillas_parameters(nom_coord.x, nom_coord.y, pmt_signal * mask) hillas_dict[tel_id] = moments nom_coord = NominalPlotter(hillas_parameters=hillas_dict, draw_axes=True) nom_coord.draw_array() except HillasParameterizationError as e: print(e) continue
def test_concentration(): geom, image, clean_mask = create_sample_image('30d') hillas = hillas_parameters(geom[clean_mask], image[clean_mask]) conc = concentration(geom, image, hillas) assert 0.1 <= conc.concentration_cog <= 0.3 assert 0.05 <= conc.concentration_pixel <= 0.2 assert 0.3 <= conc.concentration_core <= 0.6
def test_concentration(): geom, image, clean_mask = create_sample_image("30d") hillas = hillas_parameters(geom[clean_mask], image[clean_mask]) conc = concentration(geom, image, hillas) assert 0.1 <= conc.cog <= 0.3 assert 0.05 <= conc.pixel <= 0.2 assert 0.3 <= conc.core <= 0.6
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() tel_phi = {} tel_theta = {} source = hessio_event_source(filename) for event in source: hillas_dict = {} for tel_id in event.dl0.tels_with_data: geom = event.inst.subarray.tel[tel_id].camera 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].image[0] mask = tailcuts_clean(geom, pmt_signal, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask == 0] = 0 try: moments = hillas_parameters(geom, 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 plot_event(event, reco, pdf): cams = [ event.inst.subarray.tels[i].camera for i in event.r0.tels_with_data ] cams = [c for c in cams if c.cam_id in allowed_cameras] n_tels = len(cams) p = 1 params = {} pointing_azimuth = {} pointing_altitude = {} for telescope_id, dl1 in event.dl1.tel.items(): camera = event.inst.subarray.tels[telescope_id].camera if camera.cam_id not in allowed_cameras: continue nn = int(np.ceil(np.sqrt(n_tels))) ax = plt.subplot(nn, nn, p) p += 1 boundary_thresh, picture_thresh = cleaning_level[camera.cam_id] mask = tailcuts_clean(camera, dl1.image[0], boundary_thresh=boundary_thresh, picture_thresh=picture_thresh, min_number_picture_neighbors=1) # if mask.sum() < 3: # only two pixel remaining. No luck anyways. continue h = hillas_parameters( camera[mask], dl1.image[0, mask], ) disp = CameraDisplay(camera, ax=ax, title="CT{0}".format(telescope_id)) disp.pixels.set_antialiaseds(False) disp.autoupdate = False disp.add_colorbar() # Show the camera image and overlay Hillas ellipse and clean pixels disp.image = dl1.image[0] disp.cmap = 'viridis' disp.highlight_pixels(mask, color='white') disp.overlay_moments(h, color='red', linewidth=5) pointing_azimuth[ telescope_id] = event.mc.tel[telescope_id].azimuth_raw * u.rad pointing_altitude[ telescope_id] = event.mc.tel[telescope_id].altitude_raw * u.rad params[telescope_id] = h return reco.predict(params, event.inst, pointing_altitude, pointing_azimuth)
def test_convert_geometry(cam_id, rot): 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, 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
def test_no_pixels_near_cog(): geom, image, clean_mask = create_sample_image("30d") hillas = hillas_parameters(geom[clean_mask], image[clean_mask]) # remove pixels close to cog from the cleaning pixels clean_mask &= ((geom.pix_x - hillas.x)**2 + (geom.pix_y - hillas.y)**2) >= (2 * geom.pixel_width**2) conc = concentration_parameters(geom[clean_mask], image[clean_mask], hillas) assert conc.cog == 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_reconstruction(): """ a test of the complete fit procedure on one event including: • tailcut cleaning • hillas parametrisation • HillasPlane creation • direction fit • position fit in the end, proper units in the output are asserted """ filename = get_dataset_path("gamma_test.simtel.gz") fit = HillasReconstructor() tel_azimuth = {} tel_altitude = {} source = EventSourceFactory.produce(input_url=filename) for event in source: hillas_dict = {} for tel_id in event.dl0.tels_with_data: geom = event.inst.subarray.tel[tel_id].camera tel_azimuth[tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad tel_altitude[tel_id] = event.mc.tel[tel_id].altitude_raw * u.rad pmt_signal = event.r0.tel[tel_id].image[0] mask = tailcuts_clean(geom, pmt_signal, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask == 0] = 0 try: moments = hillas_parameters(geom, 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_azimuth, tel_altitude) 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
def test_convert_geometry(cam_id, rot): 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, 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
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
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) 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, 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 test_FitGammaHillas(): filename = get_path("gamma_test.simtel.gz") fit = FitGammaHillas() fit.setup_geometry(*load_hessio(filename), phi=180 * u.deg, theta=20 * u.deg) tel_geom = {} source = hessio_event_source(filename) for event in source: hillas_dict = {} for tel_id in set(event.trig.tels_with_trigger) & set( event.dl0.tels_with_data): if tel_id not in tel_geom: tel_geom[tel_id] = CameraGeometry.guess( fit.cameras(tel_id)['PixX'].to(u.m), fit.cameras(tel_id)['PixY'].to(u.m), fit.telescopes['FL'][tel_id - 1] * u.m) pmt_signal = event.dl0.tel[tel_id].adc_sums[0] mask = tailcuts_clean(tel_geom[tel_id], pmt_signal, 1, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask is False] = 0 try: moments, moms2 = hillas_parameters( fit.cameras(tel_id)['PixX'], fit.cameras(tel_id)['PixY'], 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) print(fit_result) assert fit_result return
def start(self): # n_events = self.reader.num_events source = self.reader.read() desc = "Looping through file" for event in tqdm(source, desc=desc): #, total=n_events): ev = event.count self.calibrator.calibrate(event) for tel_id in event.r0.tels_with_data: geom = self.geometry.get_camera(tel_id) nom_geom = self.geometry.get_nominal(tel_id) image = event.dl1.tel[tel_id].image[0] # Cleaning cuts = self.tail_cut[geom.cam_id] tc = tailcuts_clean(geom, image, *cuts) if not tc.any(): # self.log.warning('No image') continue # cleaned = np.ma.masked_array(image, mask=~tc) cleaned = image * tc # Hillas try: hillas = hillas_parameters(nom_geom, cleaned) except HillasParameterizationError: # self.log.warning('HillasParameterizationError') continue # embed() fig = plt.figure(figsize=(10, 10)) ax = fig.add_subplot(111) camera = CameraDisplay(nom_geom, ax=ax, image=image, cmap='viridis') camera.add_colorbar() cen_x = u.Quantity(hillas.cen_x).value cen_y = u.Quantity(hillas.cen_y).value length = u.Quantity(hillas.length).value width = u.Quantity(hillas.width).value print(cen_x, cen_y, length, width) camera.add_ellipse(centroid=(cen_x, cen_y), length=length * 2, width=width * 2, angle=hillas.psi.rad) plt.show()
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 hillas_parameters(geom, image): try: return hillas.hillas_parameters(geom, image) except hillas.HillasParameterizationError: unit = geom.pix_x.unit return hillas.MomentParameters( size=0., cen_x=np.nan * unit, cen_y=np.nan * unit, length=np.nan * unit, width=np.nan * unit, r=np.nan * unit, phi=hillas.Angle(np.nan * u.rad), psi=hillas.Angle(np.nan * u.rad), miss=np.nan * unit, skewness=None, kurtosis=None, )
def test_FitGammaHillas(): filename = get_path("gamma_test.simtel.gz") fit = FitGammaHillas() fit.setup_geometry(*load_hessio(filename), phi=180 * u.deg, theta=20 * u.deg) tel_geom = {} source = hessio_event_source(filename) for event in source: hillas_dict = {} for tel_id in set(event.trig.tels_with_trigger) & set(event.dl0.tels_with_data): if tel_id not in tel_geom: tel_geom[tel_id] = CameraGeometry.guess( fit.cameras(tel_id)["PixX"].to(u.m), fit.cameras(tel_id)["PixY"].to(u.m), fit.telescopes["FL"][tel_id - 1] * u.m, ) pmt_signal = event.dl0.tel[tel_id].adc_sums[0] mask = tailcuts_clean(tel_geom[tel_id], pmt_signal, 1, picture_thresh=10.0, boundary_thresh=5.0) pmt_signal[mask is False] = 0 try: moments, moms2 = hillas_parameters(fit.cameras(tel_id)["PixX"], fit.cameras(tel_id)["PixY"], 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) print(fit_result) assert fit_result return
def test_with_toy(): np.random.seed(42) geom = CameraGeometry.from_name('LSTCam') width = 0.03 length = 0.15 intensity = 500 xs = (0.5, 0.5, -0.5, -0.5) ys = (0.5, -0.5, 0.5, -0.5) 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.generate_2d_shower_model( centroid=(x, y), width=width, length=length, psi=psi, ) image, signal, noise = toymodel.make_toymodel_shower_image( geom, model.pdf, intensity=intensity, nsb_level_pe=5, ) result = hillas_parameters(geom, signal) assert result.x.to_value(u.m) == approx(x, rel=0.1) assert result.y.to_value(u.m) == approx(y, rel=0.1) assert result.width.to_value(u.m) == approx(width, rel=0.1) assert result.length.to_value(u.m) == approx(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
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
def test_single_pixel(): x = y = np.arange(3) x, y = np.meshgrid(x, y) geom = CameraGeometry( camera_name="testcam", pix_id=np.arange(9), pix_x=x.ravel() * u.cm, pix_y=y.ravel() * u.cm, pix_type="rectangular", pix_area=1 * u.cm**2, ) image = np.zeros((3, 3)) image[1, 1] = 10 image = image.ravel() hillas = hillas_parameters(geom, image) assert hillas.length.value == 0 assert hillas.width.value == 0 assert np.isnan(hillas.psi)
def test_convert_geometry(): filename = get_path("gamma_test.simtel.gz") cam_geom = {} source = hessio_event_source(filename) # testing a few images just for the sake of being thorough counter = 5 for event in source: 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]) # we want to test conversion of hex to rectangular pixel grid if cam_geom[tel_id].pix_type is not "hexagonal": continue print(tel_id, cam_geom[tel_id].pix_type) pmt_signal = apply_mc_calibration( #event.dl0.tel[tel_id].adc_samples[0], event.dl0.tel[tel_id].adc_sums[0], event.mc.tel[tel_id].dc_to_pe[0], event.mc.tel[tel_id].pedestal[0]) new_geom, new_signal = convert_geometry_1d_to_2d( cam_geom[tel_id], pmt_signal, cam_geom[tel_id].cam_id, add_rot=-2) unrot_geom, unrot_signal = convert_geometry_back( new_geom, new_signal, cam_geom[tel_id].cam_id, event.inst.optical_foclen[tel_id], add_rot=4) # if run as main, do some plotting if __name__ == "__main__": fig = plt.figure() plt.style.use('seaborn-talk') ax1 = fig.add_subplot(131) disp1 = CameraDisplay(cam_geom[tel_id], image=np.sum(pmt_signal, axis=1) if pmt_signal.shape[-1] == 25 else pmt_signal, ax=ax1) disp1.cmap = plt.cm.hot disp1.add_colorbar() plt.title("original geometry") ax2 = fig.add_subplot(132) disp2 = CameraDisplay(new_geom, image=np.sum(new_signal, axis=2) if new_signal.shape[-1] == 25 else new_signal, ax=ax2) disp2.cmap = plt.cm.hot disp2.add_colorbar() plt.title("slanted geometry") ax3 = fig.add_subplot(133) disp3 = CameraDisplay(unrot_geom, image=np.sum(unrot_signal, axis=1) if unrot_signal.shape[-1] == 25 else unrot_signal, ax=ax3) disp3.cmap = plt.cm.hot disp3.add_colorbar() plt.title("geometry converted back to hex") plt.show() # do some tailcuts cleaning mask1 = tailcuts_clean(cam_geom[tel_id], pmt_signal, 1, picture_thresh=10., boundary_thresh=5.) mask2 = tailcuts_clean(unrot_geom, unrot_signal, 1, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask1==False] = 0 unrot_signal[mask2==False] = 0 ''' testing back and forth conversion on hillas parameters... ''' try: moments1 = hillas_parameters(cam_geom[tel_id].pix_x, cam_geom[tel_id].pix_y, pmt_signal) moments2 = hillas_parameters(unrot_geom.pix_x, unrot_geom.pix_y, unrot_signal) except (HillasParameterizationError, AssertionError) as e: ''' we don't want this test to fail because the hillas code threw an error ''' print(e) counter -= 1 if counter < 0: return else: continue ''' test if the hillas parameters from the original geometry and the forth-and-back rotated geometry are close ''' assert np.allclose( [moments1.length.value, moments1.width.value, moments1.phi.value], [moments2.length.value, moments2.width.value, moments2.phi.value], rtol=1e-2, atol=1e-2) counter -= 1 if counter < 0: return
def test_reconstructors(reconstructors): """ a test of the complete fit procedure on one event including: • tailcut cleaning • hillas parametrisation • HillasPlane creation • direction fit • position fit in the end, proper units in the output are asserted """ filename = get_dataset_path("gamma_test_large.simtel.gz") source = event_source(filename, max_events=10) horizon_frame = AltAz() # record how many events were reconstructed by each reconstructor reconstructed_events = np.zeros((len(reconstructors))) for event in source: array_pointing = SkyCoord(az=event.mc.az, alt=event.mc.alt, frame=horizon_frame) hillas_dict = {} telescope_pointings = {} for tel_id in event.dl0.tels_with_data: geom = source.subarray.tel[tel_id].camera.geometry telescope_pointings[tel_id] = SkyCoord( alt=event.pointing.tel[tel_id].altitude, az=event.pointing.tel[tel_id].azimuth, frame=horizon_frame) pmt_signal = event.r0.tel[tel_id].waveform[0].sum(axis=1) mask = tailcuts_clean(geom, pmt_signal, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask == 0] = 0 try: moments = hillas_parameters(geom, pmt_signal) hillas_dict[tel_id] = moments except HillasParameterizationError as e: print(e) continue if len(hillas_dict) < 2: continue for count, reco_method in enumerate(reconstructors): reconstructed_events[count] += 1 reconstructor = reco_method() reconstructor_out = reconstructor.predict(hillas_dict, source.subarray, array_pointing, telescope_pointings) reconstructor_out.alt.to(u.deg) reconstructor_out.az.to(u.deg) reconstructor_out.core_x.to(u.m) assert reconstructor_out.is_valid np.testing.assert_array_less(np.zeros_like(reconstructed_events), reconstructed_events)
def test_convert_geometry(): filename = get_path("gamma_test.simtel.gz") cam_geom = {} source = hessio_event_source(filename) # testing a few images just for the sake of being thorough counter = 5 for event in source: 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]) # we want to test conversion of hex to rectangular pixel grid if cam_geom[tel_id].pix_type is not "hexagonal": continue print(tel_id, cam_geom[tel_id].pix_type) pmt_signal = apply_mc_calibration( #event.dl0.tel[tel_id].adc_samples[0], event.dl0.tel[tel_id].adc_sums[0], event.mc.tel[tel_id].dc_to_pe[0], event.mc.tel[tel_id].pedestal[0]) new_geom, new_signal = convert_geometry_1d_to_2d( cam_geom[tel_id], pmt_signal, cam_geom[tel_id].cam_id, add_rot=-2) unrot_geom, unrot_signal = convert_geometry_back( new_geom, new_signal, cam_geom[tel_id].cam_id, event.inst.optical_foclen[tel_id], add_rot=4) # if run as main, do some plotting if __name__ == "__main__": fig = plt.figure() plt.style.use('seaborn-talk') ax1 = fig.add_subplot(131) disp1 = CameraDisplay( cam_geom[tel_id], image=np.sum(pmt_signal, axis=1) if pmt_signal.shape[-1] == 25 else pmt_signal, ax=ax1) disp1.cmap = plt.cm.hot disp1.add_colorbar() plt.title("original geometry") ax2 = fig.add_subplot(132) disp2 = CameraDisplay( new_geom, image=np.sum(new_signal, axis=2) if new_signal.shape[-1] == 25 else new_signal, ax=ax2) disp2.cmap = plt.cm.hot disp2.add_colorbar() plt.title("slanted geometry") ax3 = fig.add_subplot(133) disp3 = CameraDisplay( unrot_geom, image=np.sum(unrot_signal, axis=1) if unrot_signal.shape[-1] == 25 else unrot_signal, ax=ax3) disp3.cmap = plt.cm.hot disp3.add_colorbar() plt.title("geometry converted back to hex") plt.show() # do some tailcuts cleaning mask1 = tailcuts_clean(cam_geom[tel_id], pmt_signal, 1, picture_thresh=10., boundary_thresh=5.) mask2 = tailcuts_clean(unrot_geom, unrot_signal, 1, picture_thresh=10., boundary_thresh=5.) pmt_signal[mask1 == False] = 0 unrot_signal[mask2 == False] = 0 ''' testing back and forth conversion on hillas parameters... ''' try: moments1 = hillas_parameters(cam_geom[tel_id].pix_x, cam_geom[tel_id].pix_y, pmt_signal) moments2 = hillas_parameters(unrot_geom.pix_x, unrot_geom.pix_y, unrot_signal) except (HillasParameterizationError, AssertionError) as e: ''' we don't want this test to fail because the hillas code threw an error ''' print(e) counter -= 1 if counter < 0: return else: continue ''' test if the hillas parameters from the original geometry and the forth-and-back rotated geometry are close ''' assert np.allclose([ moments1.length.value, moments1.width.value, moments1.phi.value ], [ moments2.length.value, moments2.width.value, moments2.phi.value ], rtol=1e-2, atol=1e-2) counter -= 1 if counter < 0: return
def test_hillas_container(): geom, image = create_sample_image_zeros(psi='0d') params = hillas_parameters(geom, image) assert isinstance(params, HillasParametersContainer)
def test_hillas_failure(): geom, image = create_sample_image_zeros(psi='0d') blank_image = zeros_like(image) with pytest.raises(HillasParameterizationError): hillas_parameters(geom, blank_image)
# Create a fake camera image to display: model = mock.generate_2d_shower_model(centroid=(0.2, 0.0), width=0.01, length=0.1, psi='35d') image, sig, bg = mock.make_mock_shower_image(geom, model.pdf, intensity=50, nsb_level_pe=1000) # Apply really stupid image cleaning (single threshold): clean = image.copy() clean[image <= 3.0 * image.mean()] = 0.0 # Calculate image parameters hillas = hillas_parameters(geom.pix_x, geom.pix_y, clean) print(hillas) # Show the camera image and overlay Hillas ellipse disp.image = image disp.overlay_moments(hillas, color='seagreen', linewidth=3) # Draw the neighbors of pixel 100 in red, and the neighbor-neighbors in # green for ii in geom.neighbors[130]: draw_neighbors(geom, ii, color='green') draw_neighbors(geom, 130, color='cyan', lw=2) plt.show()