def camera_waveforms(): subarray = SubarrayDescription( "test array", tel_positions={ 1: np.zeros(3) * u.m, 2: np.ones(3) * u.m }, tel_descriptions={ 1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), 2: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), }) n_pixels = subarray.tel[1].camera.n_pixels n_samples = 96 mid = n_samples // 2 pulse_sigma = 6 random = np.random.RandomState(1) x = np.arange(n_samples) # Randomize times t_pulse = random.uniform(mid - 10, mid + 10, n_pixels)[:, np.newaxis] # Create pulses y = norm.pdf(x, t_pulse, pulse_sigma) # Randomize amplitudes y *= random.uniform(100, 1000, n_pixels)[:, np.newaxis] return y, subarray
def subarray(): subarray = SubarrayDescription( "test array", tel_positions={ 1: np.zeros(3) * u.m, 2: np.zeros(3) * u.m }, tel_descriptions={ 1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), 2: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), }, ) # Create reference pulse sample_width = 0.5 reference_pulse_sample_width = sample_width / 10 reference_pulse_duration = 100 pulse_sigma = 6 ref_time = np.arange(0, reference_pulse_duration, reference_pulse_sample_width) reference_pulse = norm.pdf(ref_time, reference_pulse_duration / 2, pulse_sigma) readout = subarray.tel[1].camera.readout readout.reference_pulse_shape = np.array([reference_pulse]) readout.reference_pulse_sample_width = u.Quantity( reference_pulse_sample_width, u.ns) readout.sampling_rate = u.Quantity(1 / sample_width, u.GHz) return subarray
def test_hdf(example_subarray): import tables with tempfile.NamedTemporaryFile(suffix=".hdf5") as f: example_subarray.to_hdf(f.name) read = SubarrayDescription.from_hdf(f.name) assert example_subarray == read # test that subarrays without name (v0.8.0) work: with tables.open_file(f.name, "r+") as hdf: del hdf.root.configuration.instrument.subarray._v_attrs.name no_name = SubarrayDescription.from_hdf(f.name) assert no_name.name == "Unknown" # test with a subarray that has two different telescopes with the same # camera tel = { 1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), 2: TelescopeDescription.from_name(optics_name="SST-GCT", camera_name="CHEC"), } pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m} array = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel) with tempfile.NamedTemporaryFile(suffix=".hdf5") as f: array.to_hdf(f.name) read = SubarrayDescription.from_hdf(f.name) assert array == read
def test_hdf(example_subarray): import tables with tempfile.NamedTemporaryFile(suffix=".hdf5") as f: example_subarray.to_hdf(f.name) read = SubarrayDescription.from_hdf(f.name) assert example_subarray == read # test we can write the read subarray read.to_hdf(f.name, overwrite=True) for tel_id, tel in read.tel.items(): assert (tel.camera.geometry.frame.focal_length == tel.optics.equivalent_focal_length) # test if transforming works tel.camera.geometry.transform_to(TelescopeFrame()) # test that subarrays without name (v0.8.0) work: with tables.open_file(f.name, "r+") as hdf: del hdf.root.configuration.instrument.subarray._v_attrs.name no_name = SubarrayDescription.from_hdf(f.name) assert no_name.name == "Unknown" # test with a subarray that has two different telescopes with the same # camera tel = { 1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), 2: TelescopeDescription.from_name(optics_name="SST-GCT", camera_name="CHEC"), } pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m} array = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel) with tempfile.NamedTemporaryFile(suffix=".hdf5") as f: array.to_hdf(f.name) read = SubarrayDescription.from_hdf(f.name) assert array == read
def test_subarray_description(): pos = {} tel = {} foclen = 16 * u.m pix_x = np.arange(1764, dtype=np.float) * u.m pix_y = np.arange(1764, dtype=np.float) * u.m for ii in range(10): tel[ii] = TelescopeDescription.guess(pix_x, pix_y, foclen) pos[ii] = (np.random.uniform(200, size=2)-100) * u.m sub = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel) sub.info() assert sub.num_tels == 10 assert sub.tel[0].camera is not None assert len(sub.to_table()) == 10 subsub = sub.select_subarray("newsub", [1,2,3,4]) assert subsub.num_tels == 4 assert set(subsub.tels.keys()) == {1,2,3,4}
def test_hdf_duplicate_string_repr(tmp_path): """Test writing and reading of a subarray with two telescopes that are different but have the same name. """ # test with a subarray that has two different telescopes with the same # camera tel1 = TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam") # second telescope is almost the same and as the same str repr tel2 = deepcopy(tel1) # e.g. one mirror fell off tel2.optics.num_mirror_tiles = tel1.optics.num_mirror_tiles - 1 array = SubarrayDescription( "test array", tel_positions={1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m}, tel_descriptions={1: tel1, 2: tel2}, ) # defensive checks to make sure we are actually testing this assert len(array.telescope_types) == 2 assert str(tel1) == str(tel2) assert tel1 != tel2 path = tmp_path / "subarray.h5" array.to_hdf(path) read = SubarrayDescription.from_hdf(path) assert array == read assert ( read.tel[1].optics.num_mirror_tiles == read.tel[2].optics.num_mirror_tiles + 1 )
def test_hdf_same_camera(tmp_path): """Test writing / reading subarray to hdf5 with a subarray that has two different telescopes with the same camera """ tel = { 1: TelescopeDescription.from_name(optics_name="SST-ASTRI", camera_name="CHEC"), 2: TelescopeDescription.from_name(optics_name="SST-GCT", camera_name="CHEC"), } pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m} array = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel) path = tmp_path / "subarray.h5" array.to_hdf(path) read = SubarrayDescription.from_hdf(path) assert array == read
def read_file(cls, filename='fake_data', attribute='closed'): """ Load all the information about the telescope and its components (= parameters of the inherited classes) from an open file with name `filename`. Parameters ---------- filename: string name of the file, if no file name is given, faked data is produced attribute: if file is closed, the attribute 'close' is given, else the astropy table with the whole data read from the file is given """ ext = uf.get_file_type(filename) if attribute == 'closed': load = getattr(uf, "load_%s" % ext) instr_table = load(filename) else: instr_table = attribute tel_id, tel_num, tel_posX, tel_posY, tel_posZ = TD.get_data( instr_table) tel = cls(tel_num, tel_id, tel_posX, tel_posY, tel_posZ) opt = [] cam = [] for i in range(len(tel_id)): opt.append(Optics.read_file(filename, tel_id[i], instr_table)[0]) cam.append(Camera.read_file(filename, tel_id[i], instr_table)[0]) return tel, opt, cam, instr_table
def init_container(self): url = self.url max_events = self.max_events chec_tel = 0 data = DataContainer() data.meta['origin'] = "targetio" # some targetio_event_source specific parameters data.meta['input'] = url data.meta['max_events'] = max_events data.meta['n_rows'] = self.n_rows data.meta['n_columns'] = self.n_columns data.meta['n_blocks'] = self.n_blocks data.meta['n_blockphases'] = N_BLOCKSAMPLES data.meta['n_cells'] = self.n_cells data.meta['n_modules'] = self.n_modules data.meta['tm'] = np.arange(self.n_pix, dtype=np.uint16) // self.n_tmpix data.meta['tmpix'] = np.arange(self.n_pix, dtype=np.uint16) % self.n_tmpix pix_pos = self.pixel_pos * u.m foclen = self.optical_foclen * u.m teldesc = TelescopeDescription.guess(*pix_pos, foclen) data.inst.subarray.tels[chec_tel] = teldesc self.data = data
def subarray_lst(): telid = 1 subarray = SubarrayDescription( "test array lst", tel_positions={1: np.zeros(3) * u.m, 2: np.ones(3) * u.m}, tel_descriptions={ 1: TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam"), 2: TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam"), }, ) n_pixels = subarray.tel[telid].camera.geometry.n_pixels n_samples = 30 selected_gain_channel = np.zeros(n_pixels, dtype=np.int) return subarray, telid, selected_gain_channel, n_pixels, n_samples
def create_subarray(self, tel_id=1): """ Obtain the subarray from the EventSource Returns ------- ctapipe.instrument.SubarrayDecription """ # camera info from LSTCam-[geometry_version].camgeom.fits.gz file camera = load_camera_geometry(version=self.geometry_version) tel_descr = TelescopeDescription( name='LST', tel_type='LST', optics=OPTICS, camera=camera ) 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 return subarray
def read_file(cls,filename='fake_data',attribute='closed'): """ Load all the information about the telescope and its components (= parameters of the inherited classes) from an open file with name `filename`. Parameters ---------- filename: string name of the file, if no file name is given, faked data is produced attribute: if file is closed, the attribute 'close' is given, else the astropy table with the whole data read from the file is given """ ext = uf.get_file_type(filename) if attribute == 'closed': load = getattr(uf,"load_%s" % ext) instr_table = load(filename) else: instr_table = attribute tel_id, tel_num,tel_posX,tel_posY,tel_posZ = TD.get_data(instr_table) tel = cls(tel_num,tel_id,tel_posX,tel_posY,tel_posZ) opt = [] cam = [] for i in range(len(tel_id)): opt.append(Optics.read_file(filename,tel_id[i],instr_table)[0]) cam.append(Camera.read_file(filename,tel_id[i],instr_table)[0]) return tel,opt,cam,instr_table
def ctapipe_subarray(self): from ctapipe.instrument import TelescopeDescription, SubarrayDescription, \ CameraGeometry, CameraReadout, CameraDescription, OpticsDescription import astropy.units as u geom = CameraGeometry("sstcam", self.mapping.pixel.i, u.Quantity(self.mapping.pixel.x, 'm'), u.Quantity(self.mapping.pixel.y, 'm'), u.Quantity(self.mapping.pixel.size, 'm')**2, 'square') readout = CameraReadout( "sstcam", u.Quantity(1 / self.waveform_sample_width, "GHz"), self.photoelectron_pulse.amplitude[None, :], u.Quantity(self.photoelectron_pulse.sample_width, "ns")) camera = CameraDescription("sstcam", geom, readout) optics = OpticsDescription.from_name('SST-ASTRI') telescope = TelescopeDescription("SST", "SST", optics, camera) subarray = SubarrayDescription( 'toy', tel_positions={1: [0, 0, 0] * u.m}, tel_descriptions={1: telescope}, ) return subarray
def test_array_display(): from ctapipe.visualization.mpl_array import ArrayDisplay # build a test subarray: tels = dict() tel_pos = dict() for ii, pos in enumerate([[0, 0, 0], [100, 0, 0], [-100, 0, 0]] * u.m): tels[ii + 1] = TelescopeDescription.from_name("MST", "NectarCam") tel_pos[ii + 1] = pos sub = SubarrayDescription(name="TestSubarray", tel_positions=tel_pos, tel_descriptions=tels) ad = ArrayDisplay(sub) ad.set_vector_rho_phi(1 * u.m, 90 * u.deg) # try setting a value vals = ones(sub.num_tels) ad.values = vals assert (vals == ad.values).all() # test using hillas params: hillas_dict = { 1: HillasParametersContainer(length=1.0 * u.m, phi=90 * u.deg), 2: HillasParametersContainer(length=200 * u.cm, phi="95deg"), } ad.set_vector_hillas(hillas_dict) ad.add_labels() ad.remove_labels()
def plot_telescope_layout(tel_layout_file_name): layout_file = "/Users/alicedonini/PycharmProjects/Pointing_tool/layout-3AL4-BN15-MST.txt" grd_coords = pd.read_csv(layout_file, header=None, delimiter=" ", names=["x", "y", "z"], engine='python') # convert to m grd_coords = grd_coords / 100 # create a dictionary with the tel position on the ground by tel_id and the tel description tel_descr = {} G_coords = {} for tel_id, coord in enumerate(grd_coords.values, 1): G_coords[tel_id] = coord * u.m tel_descr[tel_id] = TelescopeDescription.from_name( optics_name='MST', camera_name='NectarCam') # create the subarray sub = SubarrayDescription(name="Baseline only MST", tel_positions=G_coords, tel_descriptions=tel_descr) #sub.info() #sub.to_table(kind='optics') # display the array plt.figure(num=None, figsize=(7, 7), facecolor='w', edgecolor='k') disp = ArrayDisplay(sub, tel_scale=3.0) return sub
def test_subarray_description(): pos = {} tel = {} foclen = 16 * u.m pix_x = np.arange(1764, dtype=np.float) * u.m pix_y = np.arange(1764, dtype=np.float) * u.m for ii in range(10): tel[ii] = TelescopeDescription.guess(pix_x, pix_y, foclen) pos[ii] = np.random.uniform(-100, 100, size=2) * u.m sub = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel) sub.info() assert sub.num_tels == 10 assert sub.tel[0].camera is not None assert len(sub.to_table()) == 10 subsub = sub.select_subarray("newsub", [1, 2, 3, 4]) assert subsub.num_tels == 4 assert set(subsub.tels.keys()) == {1, 2, 3, 4}
def prepare_subarray_info(self, telescope_descriptions, header): """ Constructs a SubarrayDescription object from the ``telescope_descriptions`` given by ``SimTelFile`` Parameters ---------- telescope_descriptions: dict telescope descriptions as given by ``SimTelFile.telescope_descriptions`` header: dict header as returned by ``SimTelFile.header`` Returns ------- SubarrayDescription : instrumental information """ tel_descriptions = {} # tel_id : TelescopeDescription tel_positions = {} # tel_id : TelescopeDescription for tel_id, telescope_description in telescope_descriptions.items(): cam_settings = telescope_description['camera_settings'] n_pixels = cam_settings['n_pixels'] focal_length = u.Quantity(cam_settings['focal_length'], u.m) try: telescope = guess_telescope(n_pixels, focal_length) except ValueError: telescope = UNKNOWN_TELESCOPE camera = self._camera_cache.get(telescope.camera_name) if camera is None: camera = build_camera_geometry(cam_settings, telescope) self._camera_cache[telescope.camera_name] = camera optics = OpticsDescription( name=telescope.name, num_mirrors=telescope.n_mirrors, equivalent_focal_length=focal_length, mirror_area=u.Quantity(cam_settings['mirror_area'], u.m**2), num_mirror_tiles=cam_settings['n_mirrors'], ) tel_descriptions[tel_id] = TelescopeDescription( name=telescope.name, type=telescope.type, camera=camera, optics=optics, ) tel_idx = np.where(header['tel_id'] == tel_id)[0][0] tel_positions[tel_id] = header['tel_pos'][tel_idx] * u.m return SubarrayDescription( "MonteCarloArray", tel_positions=tel_positions, tel_descriptions=tel_descriptions, )
def test_muon_efficiency_fit(): from ctapipe.instrument import TelescopeDescription, SubarrayDescription from ctapipe.coordinates import TelescopeFrame, CameraFrame from ctapipe.image.muon.intensity_fitter import image_prediction, MuonIntensityFitter telescope = TelescopeDescription.from_name('LST', 'LSTCam') subarray = SubarrayDescription( 'LSTMono', {0: [0, 0, 0] * u.m}, {0: telescope}, ) center_x = 0.8 * u.deg center_y = 0.4 * u.deg radius = 1.2 * u.deg ring_width = 0.05 * u.deg impact_parameter = 5 * u.m phi = 0 * u.rad efficiency = 0.5 focal_length = telescope.optics.equivalent_focal_length geom = telescope.camera.geometry mirror_radius = np.sqrt(telescope.optics.mirror_area / np.pi) pixel_diameter = 2 * u.rad * (np.sqrt(geom.pix_area / np.pi) / focal_length).to_value(u.dimensionless_unscaled) tel = CameraFrame( x=geom.pix_x, y=geom.pix_y, focal_length=focal_length, rotation=geom.cam_rotation, ).transform_to(TelescopeFrame()) x = tel.fov_lon y = tel.fov_lat image = image_prediction( mirror_radius, hole_radius=0 * u.m, impact_parameter=impact_parameter, phi=phi, center_x=center_x, center_y=center_y, radius=radius, ring_width=ring_width, pixel_x=x, pixel_y=y, pixel_diameter=pixel_diameter[0] ) fitter = MuonIntensityFitter(subarray=subarray) result = fitter( tel_id=0, center_x=center_x, center_y=center_y, radius=radius, image=image * efficiency, pedestal=np.full_like(image, 1.1) ) assert u.isclose(result.impact, impact_parameter, rtol=0.05) assert u.isclose(result.width, ring_width, rtol=0.05) assert u.isclose(result.optical_efficiency, efficiency, rtol=0.05)
def test_array_display(): """ check that we can do basic array display functionality """ from ctapipe.visualization.mpl_array import ArrayDisplay from ctapipe.image import timing_parameters # build a test subarray: tels = dict() tel_pos = dict() for ii, pos in enumerate([[0, 0, 0], [100, 0, 0], [-100, 0, 0]] * u.m): tels[ii + 1] = TelescopeDescription.from_name("MST", "NectarCam") tel_pos[ii + 1] = pos sub = SubarrayDescription(name="TestSubarray", tel_positions=tel_pos, tel_descriptions=tels) ad = ArrayDisplay(sub) ad.set_vector_rho_phi(1 * u.m, 90 * u.deg) # try setting a value vals = ones(sub.num_tels) ad.values = vals assert (vals == ad.values).all() # test using hillas params: hillas_dict = { 1: HillasParametersContainer(length=100.0 * u.m, psi=90 * u.deg), 2: HillasParametersContainer(length=20000 * u.cm, psi="95deg"), } grad = 2 intercept = 1 geom = CameraGeometry.from_name("LSTCam") rot_angle = 20 * u.deg hillas = HillasParametersContainer(x=0 * u.m, y=0 * u.m, psi=rot_angle) timing_rot20 = timing_parameters( geom, image=ones(geom.n_pixels), peak_time=intercept + grad * geom.pix_x.value, hillas_parameters=hillas, cleaning_mask=ones(geom.n_pixels, dtype=bool), ) gradient_dict = { 1: timing_rot20.slope.value, 2: timing_rot20.slope.value, } ad.set_vector_hillas( hillas_dict=hillas_dict, length=500, time_gradient=gradient_dict, angle_offset=0 * u.deg, ) ad.set_line_hillas(hillas_dict, range=300) ad.add_labels() ad.remove_labels()
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 self.data.meta['origin'] = 'LSTCAM' # 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', tel_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 get_telescope_description(optics_name: str, cam_name: str) -> TelescopeDescription: if telescope_descriptions.get(optics_name) is None: telescope_descriptions[optics_name] = dict() if telescope_descriptions[optics_name].get(cam_name) is None: telescope_descriptions[optics_name][ cam_name] = TelescopeDescription.from_name(optics_name, cam_name) return telescope_descriptions[optics_name][cam_name]
def __init__(self, config=None, tool=None, **kwargs): super().__init__(config=config, tool=tool, **kwargs) from protozfits import File self.file = File(self.input_url) # TODO: Correct pixel ordering self._tel_desc = TelescopeDescription.from_name( optics_name='SST-1M', camera_name='DigiCam' )
def _fill_instrument_info(data, pyhessio_file, camera_geometry, camera): """ fill the data.inst structure with instrumental information. Parameters ---------- data: DataContainer data container to fill in """ if not data.inst.telescope_ids: data.inst.telescope_ids = list(pyhessio_file.get_telescope_ids()) data.inst.subarray = SubarrayDescription("MonteCarloArray") for tel_id in data.inst.telescope_ids: try: pix_pos = pyhessio_file.get_pixel_position(tel_id) * u.m foclen = pyhessio_file.get_optical_foclen(tel_id) * u.m mirror_area = pyhessio_file.get_mirror_area(tel_id) * u.m**2 num_tiles = pyhessio_file.get_mirror_number(tel_id) tel_pos = pyhessio_file.get_telescope_position(tel_id) * u.m tel = TelescopeDescription.guess(*pix_pos, foclen) tel.optics.mirror_area = mirror_area tel.optics.num_mirror_tiles = num_tiles data.inst.subarray.tels[tel_id] = tel data.inst.subarray.positions[tel_id] = tel_pos # deprecated fields that will become part of # TelescopeDescription or SubrrayDescription data.inst.optical_foclen[tel_id] = foclen data.inst.pixel_pos[tel_id] = pix_pos data.inst.tel_pos[tel_id] = tel_pos nchans = pyhessio_file.get_num_channel(tel_id) npix = pyhessio_file.get_num_pixels(tel_id) data.inst.num_channels[tel_id] = nchans data.inst.num_pixels[tel_id] = npix data.inst.mirror_dish_area[tel_id] = mirror_area data.inst.mirror_numtiles[tel_id] = num_tiles geometry = camera_geometry patch_matrix = \ utils.geometry.compute_patch_matrix(camera=camera) cluster_7_matrix = \ utils.geometry.compute_cluster_matrix_7(camera=camera) cluster_19_matrix = \ utils.geometry.compute_cluster_matrix_19(camera=camera) data.inst.geom[tel_id] = geometry data.inst.cluster_matrix_7[tel_id] = cluster_7_matrix data.inst.cluster_matrix_19[tel_id] = cluster_19_matrix data.inst.patch_matrix[tel_id] = patch_matrix except HessioGeneralError: pass
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)
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 subarray_1_LST(): subarray = SubarrayDescription( "One LST", tel_positions={1: np.zeros(3) * u.m}, tel_descriptions={ 1: TelescopeDescription.from_name(optics_name="LST", camera_name="LSTCam") }, ) return subarray
def test_telescope_description(): # setup a dummy telescope that look like an MST with FlashCam foclen = 16 * u.m pix_x = np.arange(1764, dtype=np.float) * u.m pix_y = np.arange(1764, dtype=np.float) * u.m tel = TelescopeDescription.guess(pix_x, pix_y, foclen) assert tel.camera.cam_id == 'FlashCam' assert tel.optics.tel_type == 'MST' assert str(tel) == 'MST:FlashCam'
def test_telescope_description(): # setup a dummy telescope that look like an MST with FlashCam foclen = 16*u.m pix_x = np.arange(1764, dtype=np.float) * u.m pix_y = np.arange(1764, dtype=np.float) * u.m tel = TelescopeDescription.guess(pix_x, pix_y, foclen) assert tel.camera.cam_id == 'FlashCam' assert tel.optics.tel_type == 'MST' assert str(tel) == 'MST:FlashCam'
def example_subarray(n_tels=10): """ generate a simple subarray for testing purposes """ pos = {} tel = {} for tel_id in range(1, n_tels + 1): tel[tel_id] = TelescopeDescription.from_name( optics_name="MST", camera_name="NectarCam" ) pos[tel_id] = np.random.uniform(-100, 100, size=3) * u.m return SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel)
def test_tel_ids_to_mask(example_subarray): lst = TelescopeDescription.from_name("LST", "LSTCam") subarray = SubarrayDescription( "someone_counted_in_binary", tel_positions={1: [0, 0, 0] * u.m, 10: [50, 0, 0] * u.m}, tel_descriptions={1: lst, 10: lst}, ) assert np.all(subarray.tel_ids_to_mask([]) == [False, False]) assert np.all(subarray.tel_ids_to_mask([1]) == [True, False]) assert np.all(subarray.tel_ids_to_mask([10]) == [False, True]) assert np.all(subarray.tel_ids_to_mask([1, 10]) == [True, True])
def test_array_display(): from ctapipe.visualization.mpl_array import ArrayDisplay from ctapipe.image.timing_parameters import timing_parameters # build a test subarray: tels = dict() tel_pos = dict() for ii, pos in enumerate([[0, 0, 0], [100, 0, 0], [-100, 0, 0]] * u.m): tels[ii + 1] = TelescopeDescription.from_name("MST", "NectarCam") tel_pos[ii + 1] = pos sub = SubarrayDescription(name="TestSubarray", tel_positions=tel_pos, tel_descriptions=tels) ad = ArrayDisplay(sub) ad.set_vector_rho_phi(1 * u.m, 90 * u.deg) # try setting a value vals = ones(sub.num_tels) ad.values = vals assert (vals == ad.values).all() # test using hillas params: hillas_dict = { 1: HillasParametersContainer(length=100.0 * u.m, psi=90 * u.deg), 2: HillasParametersContainer(length=20000 * u.cm, psi="95deg"), } grad = 2 intercept = 1 rot_angle = 20 * u.deg timing_rot20 = timing_parameters(pix_x=arange(4) * u.deg, pix_y=zeros(4) * u.deg, image=ones(4), peak_time=intercept * u.ns + grad * arange(4) * u.ns, rotation_angle=rot_angle) gradient_dict = { 1: timing_rot20.gradient.value, 2: timing_rot20.gradient.value, } ad.set_vector_hillas(hillas_dict=hillas_dict, length=500, time_gradient=gradient_dict, angle_offset=0 * u.deg) ad.set_line_hillas(hillas_dict, range=300) ad.add_labels() ad.remove_labels()
def _init_container(self): """ Prepare the ctapipe event container, and fill it with the information that does not change with event, including the instrument information. """ chec_tel = 0 data = TargetIODataContainer() data.meta['origin'] = "targetio" data.meta['input'] = self.input_url data.meta['max_events'] = self.max_events # Instrument information camera = CameraGeometry( "CHEC", pix_id=np.arange(self._n_pixels), pix_x=self._xpix, pix_y=self._ypix, pix_area=None, pix_type='rectangular', ) optics = OpticsDescription( name="ASTRI", num_mirrors=2, equivalent_focal_length=self._optical_foclen, mirror_area=self._mirror_area, num_mirror_tiles=2, ) tel_descriptions = { chec_tel: TelescopeDescription( name="ASTRI", type="SST", camera=camera, optics=optics, ) } tel_positions = { chec_tel: u.Quantity(0, u.m) } data.inst.subarray =SubarrayDescription( "CHECMonoArray", tel_positions=tel_positions, tel_descriptions=tel_descriptions, ) self._data = data
def subarray(): lst = TelescopeDescription.from_name("LST", "LSTCam") tels = [lst] * 4 positions = { 1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m, 3: [0, 50, 0] * u.m, 4: [50, 50, 0] * u.m, } descriptions = {i: t for i, t in enumerate(tels, start=1)} return SubarrayDescription("test", positions, descriptions)
def prepare_subarray_info(telescope_descriptions, header): """ Constructs a SubarrayDescription object from the ``telescope_descriptions`` given by ``SimTelFile`` Parameters ---------- telescope_descriptions: dict telescope descriptions as given by ``SimTelFile.telescope_descriptions`` header: dict header as returned by ``SimTelFile.header`` Returns ------- SubarrayDescription : instrumental information """ tel_descriptions = {} # tel_id : TelescopeDescription tel_positions = {} # tel_id : TelescopeDescription for tel_id, telescope_description in telescope_descriptions.items(): cam_settings = telescope_description['camera_settings'] tel_description = TelescopeDescription.guess( cam_settings['pixel_x'] * u.m, cam_settings['pixel_y'] * u.m, equivalent_focal_length=cam_settings['focal_length'] * u.m ) tel_description.optics.mirror_area = ( cam_settings['mirror_area'] * u.m ** 2 ) tel_description.optics.num_mirror_tiles = ( cam_settings['n_mirrors'] ) tel_descriptions[tel_id] = tel_description tel_idx = np.where(header['tel_id'] == tel_id)[0][0] tel_positions[tel_id] = header['tel_pos'][tel_idx] * u.m return SubarrayDescription( "MonteCarloArray", tel_positions=tel_positions, tel_descriptions=tel_descriptions, )
def test_subarray_description(): pos = {} tel = {} n_tels = 10 for tel_id in range(1, n_tels + 1): tel[tel_id] = TelescopeDescription.from_name( optics_name="MST", camera_name="NectarCam", ) pos[tel_id] = np.random.uniform(-100, 100, size=3) * u.m sub = SubarrayDescription( "test array", tel_positions=pos, tel_descriptions=tel ) assert len(sub.telescope_types) == 1 assert str(sub) == "test array" assert sub.num_tels == n_tels assert len(sub.tel_ids) == n_tels assert sub.tel_ids[0] == 1 assert sub.tel[1].camera is not None assert 0 not in sub.tel # check that there is no tel 0 (1 is first above) assert len(sub.to_table()) == n_tels assert len(sub.camera_types) == 1 # only 1 camera type assert sub.camera_types[0] == 'NectarCam' assert sub.optics_types[0].equivalent_focal_length.to_value(u.m) == 16.0 assert sub.telescope_types[0] == 'MST:NectarCam' assert sub.tel_coords assert isinstance(sub.tel_coords, SkyCoord) assert len(sub.tel_coords) == n_tels subsub = sub.select_subarray("newsub", [2, 3, 4, 6]) assert subsub.num_tels == 4 assert set(subsub.tels.keys()) == {2, 3, 4, 6} assert subsub.tel_indices[6] == 3 assert subsub.tel_ids[3] == 6 assert len(sub.to_table(kind='optics')) == 1
def _init_container(self): """ Prepare the ctapipe event container, and fill it with the information that does not change with event, including the instrument information. """ chec_tel = 0 data = TargetIODataContainer() data.meta['origin'] = "targetio" data.meta['input'] = self.input_url data.meta['max_events'] = self.max_events # Instrument information pix_pos = self._pixel_pos * u.m foclen = self._optical_foclen * u.m teldesc = TelescopeDescription.guess(*pix_pos, foclen) data.inst.subarray.tels[chec_tel] = teldesc self._data = data
import matplotlib.pylab as plt import numpy as np from astropy import units as u from matplotlib.animation import FuncAnimation from ctapipe.image import toymodel from ctapipe.instrument import TelescopeDescription from ctapipe.visualization import CameraDisplay if __name__ == '__main__': plt.style.use("ggplot") fig, ax = plt.subplots() # load the camera tel = TelescopeDescription.from_name("SST-1M", "DigiCam") geom = tel.camera fov = 0.3 maxwid = 0.05 maxlen = 0.1 disp = CameraDisplay(geom, ax=ax) disp.cmap = 'inferno' disp.add_colorbar(ax=ax) def update(frame): x, y = np.random.uniform(-fov, fov, size=2) width = np.random.uniform(0.01, maxwid) length = np.random.uniform(width, maxlen) angle = np.random.uniform(0, 180)
def _display_camera_animation(self): # plt.style.use("ggplot") fig = plt.figure(num="ctapipe Camera Demo", figsize=(7, 7)) ax = plt.subplot(111) # load the camera tel = TelescopeDescription.from_name(optics_name=self.optics, camera_name=self.camera) geom = tel.camera # poor-man's coordinate transform from telscope to camera frame (it's # better to use ctapipe.coordiantes when they are stable) foclen = tel.optics.equivalent_focal_length.to(geom.pix_x.unit).value fov = np.deg2rad(4.0) scale = foclen minwid = np.deg2rad(0.1) maxwid = np.deg2rad(0.3) maxlen = np.deg2rad(0.5) self.log.debug("scale={} m, wid=({}-{})".format(scale, minwid, maxwid)) disp = CameraDisplay( geom, ax=ax, autoupdate=True, title="{}, f={}".format(tel, tel.optics.equivalent_focal_length) ) disp.cmap = plt.cm.terrain def update(frame): centroid = np.random.uniform(-fov, fov, size=2) * scale width = np.random.uniform(0, maxwid-minwid) * scale + minwid length = np.random.uniform(0, maxlen) * scale + width angle = np.random.uniform(0, 360) intens = np.random.exponential(2) * 500 model = toymodel.generate_2d_shower_model(centroid=centroid, width=width, length=length, psi=angle * u.deg) self.log.debug( "Frame=%d width=%03f length=%03f intens=%03d", frame, width, length, intens ) image, sig, bg = toymodel.make_toymodel_shower_image( geom, model.pdf, intensity=intens, nsb_level_pe=3, ) # alternate between cleaned and raw images if self._counter == self.cleanframes: plt.suptitle("Image Cleaning ON") self.imclean = True if self._counter == self.cleanframes * 2: plt.suptitle("Image Cleaning OFF") self.imclean = False self._counter = 0 disp.clear_overlays() if self.imclean: cleanmask = tailcuts_clean(geom, image, picture_thresh=10.0, boundary_thresh=5.0) for ii in range(2): dilate(geom, cleanmask) image[cleanmask == 0] = 0 # zero noise pixels try: hillas = hillas_parameters(geom, image) disp.overlay_moments(hillas, with_label=False, color='red', alpha=0.7, linewidth=2, linestyle='dashed') except HillasParameterizationError: disp.clear_overlays() pass self.log.debug("Frame=%d image_sum=%.3f max=%.3f", self._counter, image.sum(), image.max()) disp.image = image if self.autoscale: disp.set_limits_percent(95) else: disp.set_limits_minmax(-5, 200) disp.axes.figure.canvas.draw() self._counter += 1 return [ax, ] frames = None if self.num_events == 0 else self.num_events repeat = True if self.num_events == 0 else False self.log.info("Running for {} frames".format(frames)) self.anim = FuncAnimation(fig, update, interval=self.delay, frames=frames, repeat=repeat, blit=self.blit) if self.display: plt.show()