def predict(self, hillas_parameters, tel_x, tel_y, array_direction): """ Parameters ---------- hillas_parameters: dict Dictionary containing Hillas parameters for all telescopes in reconstruction tel_x: dict Dictionary containing telescope position on ground for all telescopes in reconstruction tel_y: dict Dictionary containing telescope position on ground for all telescopes in reconstruction array_direction: HorizonFrame Pointing direction of the array Returns ------- """ src_x, src_y, err_x, err_y = self.reconstruct_nominal( hillas_parameters) core_x, core_y, core_err_x, core_err_y = self.reconstruct_tilted( hillas_parameters, tel_x, tel_y) err_x *= u.rad err_y *= u.rad nom = NominalFrame(x=src_x * u.rad, y=src_y * u.rad, array_direction=array_direction) horiz = nom.transform_to(HorizonFrame()) result = ReconstructedShowerContainer() result.alt, result.az = horiz.alt, horiz.az tilt = TiltedGroundFrame(x=core_x * u.m, y=core_y * u.m, pointing_direction=array_direction) grd = project_to_ground(tilt) result.core_x = grd.x result.core_y = grd.y x_max = self.reconstruct_xmax(nom.x, nom.y, tilt.x, tilt.y, hillas_parameters, tel_x, tel_y, 90 * u.deg - array_direction.alt) result.core_uncert = np.sqrt(core_err_x * core_err_x + core_err_y * core_err_y) * u.m result.tel_ids = [h for h in hillas_parameters.keys()] result.average_size = np.mean( [h.size for h in hillas_parameters.values()]) result.is_valid = True src_error = np.sqrt(err_x * err_x + err_y * err_y) result.alt_uncert = src_error.to(u.deg) result.az_uncert = src_error.to(u.deg) result.h_max = x_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_parameters, tel_x, tel_y, array_direction): """ Parameters ---------- hillas_parameters: dict Dictionary containing Hillas parameters for all telescopes in reconstruction tel_x: dict Dictionary containing telescope position on ground for all telescopes in reconstruction tel_y: dict Dictionary containing telescope position on ground for all telescopes in reconstruction array_direction: HorizonFrame Pointing direction of the array Returns ------- """ src_x, src_y, err_x, err_y = self.reconstruct_nominal(hillas_parameters) core_x, core_y, core_err_x, core_err_y = self.reconstruct_tilted( hillas_parameters, tel_x, tel_y) err_x *= u.rad err_y *= u.rad nom = NominalFrame(x=src_x * u.rad, y=src_y * u.rad, array_direction=array_direction) horiz = nom.transform_to(HorizonFrame()) result = ReconstructedShowerContainer() result.alt, result.az = horiz.alt, horiz.az tilt = TiltedGroundFrame(x=core_x * u.m, y=core_y * u.m, pointing_direction=array_direction) grd = project_to_ground(tilt) result.core_x = grd.x result.core_y = grd.y x_max = self.reconstruct_xmax(nom.x, nom.y, tilt.x, tilt.y, hillas_parameters, tel_x, tel_y, 90 * u.deg - array_direction.alt) result.core_uncert = np.sqrt( core_err_x * core_err_x + core_err_y * core_err_y) * u.m result.tel_ids = [h for h in hillas_parameters.keys()] result.average_size = np.mean([h.size for h in hillas_parameters.values()]) result.is_valid = True src_error = np.sqrt(err_x * err_x + err_y * err_y) result.alt_uncert = src_error.to(u.deg) result.az_uncert = src_error.to(u.deg) result.h_max = x_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_dict, inst, tel_phi, tel_theta, seed_pos=(0, 0)): '''The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict : python dictionary dictionary with telescope IDs as key and MomentParameters instances as values seed_pos : python tuple shape (2) tuple with a possible seed for the core position fit (e.g. CoG of all telescope images) ''' self.get_great_circles(hillas_dict, inst, tel_phi, tel_theta) # algebraic direction estimate dir1 = self.fit_origin_crosses()[0] # direction estimate using numerical minimisation # does not really improve the fit for now # dir2 = self.fit_origin_minimise(dir1) # core position estimate using numerical minimisation # pos = self.fit_core_minimise(seed_pos) # core position estimate using a geometric approach pos = self.fit_core_crosses() # container class for reconstructed showers ''' result = ReconstructedShowerContainer() (phi, theta) = linalg.get_phi_theta(dir1).to(u.deg) # TODO make sure az and phi turn in same direction... result.alt, result.az = 90 * u.deg - theta, phi result.core_x = pos[0] result.core_y = pos[1] result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean([h.size for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = np.nan result.az_uncert = np.nan result.core_uncert = np.nan result.h_max = np.nan result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_dict, inst, tel_phi, tel_theta, seed_pos=(0, 0)): '''The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict : python dictionary dictionary with telescope IDs as key and MomentParameters instances as values seed_pos : python tuple shape (2) tuple with a possible seed for the core position fit (e.g. CoG of all telescope images) ''' self.get_great_circles(hillas_dict, inst, tel_phi, tel_theta) # algebraic direction estimate dir1 = self.fit_origin_crosses()[0] # direction estimate using numerical minimisation # does not really improve the fit for now # dir2 = self.fit_origin_minimise(dir1) # core position estimate using numerical minimisation # pos = self.fit_core_minimise(seed_pos) # core position estimate using a geometric approach pos = self.fit_core_crosses() # container class for reconstructed showers ''' result = ReconstructedShowerContainer() (phi, theta) = linalg.get_phi_theta(dir1).to(u.deg) # TODO make sure az and phi turn in same direction... result.alt, result.az = 90 * u.deg - theta, phi result.core_x = pos[0] result.core_y = pos[1] result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean([h.size for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = np.nan result.az_uncert = np.nan result.core_uncert = np.nan result.h_max = np.nan result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_dict, inst, tel_phi, tel_theta, seed_pos=(0, 0)): """The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict : python dictionary dictionary with telescope IDs as key and MomentParameters instances as values seed_pos : python tuple shape (2) tuple with a possible seed for the core position fit (e.g. CoG of all telescope images) Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 """ # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}".format( len(hillas_dict))) self.get_great_circles(hillas_dict, inst.subarray, tel_phi, tel_theta) # algebraic direction estimate dir, err_est_dir = self.fit_origin_crosses() # core position estimate using a geometric approach pos, err_est_pos = self.fit_core_crosses() # numerical minimisations do not really improve the fit # direction estimate using numerical minimisation # dir = self.fit_origin_minimise(dir) # # core position estimate using numerical minimisation # pos = self.fit_core_minimise(seed_pos) # container class for reconstructed showers result = ReconstructedShowerContainer() phi, theta = linalg.get_phi_theta(dir).to(u.deg) # TODO fix coordinates! result.alt, result.az = 90 * u.deg - theta, -phi result.core_x = pos[0] result.core_y = pos[1] result.core_uncert = err_est_pos result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean([h.size for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = self.fit_h_max(hillas_dict, inst.subarray, tel_phi, tel_theta) result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_dict, inst, pointing_alt, pointing_az): ''' The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict: dict dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description pointing_alt: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing altitude pointing_az: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing azimuth Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 ''' # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}".format( len(hillas_dict))) self.initialize_hillas_planes(hillas_dict, inst.subarray, pointing_alt, pointing_az) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() alt = u.Quantity(list(pointing_alt.values())) az = u.Quantity(list(pointing_az.values())) if np.any(alt != alt[0]) or np.any(az != az[0]): raise ValueError('Divergent pointing not supported') pointing_direction = SkyCoord(alt=alt[0], az=az[0], frame='altaz') # core position estimate using a geometric approach core_pos = self.estimate_core_position(hillas_dict, pointing_direction) # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max() # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. result.alt, result.az = lat, -lon result.core_x = core_pos[0] result.core_y = core_pos[1] result.core_uncert = np.nan result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean( [h.intensity for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_dict, inst, pointing_alt, pointing_az, seed_pos=(0, 0)): """The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict : python dictionary dictionary with telescope IDs as key and MomentParameters instances as values inst : ctapipe.io.InstrumentContainer instrumental description pointing_alt: pointing_az: seed_pos : python tuple shape (2) tuple with a possible seed for the core position fit (e.g. CoG of all telescope images) Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 """ # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}" .format(len(hillas_dict))) self.inititialize_hillas_planes( hillas_dict, inst.subarray, pointing_alt, pointing_az ) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() # core position estimate using a geometric approach pos, err_est_pos = self.estimate_core_position() # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max(hillas_dict, inst.subarray, pointing_alt, pointing_az) result.alt, result.az = lat, lon result.core_x = pos[0] result.core_y = pos[1] result.core_uncert = err_est_pos result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean([h.size for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def predict(self, hillas_dict, inst, pointing_alt, pointing_az): ''' The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict: dict dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description pointing_alt: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing altitude pointing_az: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing azimuth Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 ''' # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}" .format(len(hillas_dict))) self.initialize_hillas_planes( hillas_dict, inst.subarray, pointing_alt, pointing_az ) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() alt = u.Quantity(list(pointing_alt.values())) az = u.Quantity(list(pointing_az.values())) if np.any(alt != alt[0]) or np.any(az != az[0]): warnings.warn('Divergent pointing not supported') telescope_pointing = SkyCoord(alt=alt[0], az=az[0], frame=HorizonFrame()) # core position estimate using a geometric approach core_pos = self.estimate_core_position(hillas_dict, telescope_pointing) # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max() # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. result.alt, result.az = lat, -lon result.core_x = core_pos[0] result.core_y = core_pos[1] result.core_uncert = np.nan result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean([h.intensity for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result