def test_image_prediction(self): pixel_x = np.array([0]) * u.deg pixel_y = np.array([0]) * u.deg image = np.array([1]) pixel_area = np.array([1]) * u.deg * u.deg self.impact_reco.set_event_properties( {1: image}, {1: pixel_x}, {1: pixel_y}, {1: pixel_area}, {1: "CHEC"}, {1: 0 * u.m}, {1: 0 * u.m}, array_direction=[0 * u.deg, 0 * u.deg], ) """First check image prediction by directly accessing the function""" pred = self.impact_reco.image_prediction( "CHEC", zenith=0, azimuth=0, energy=1, impact=50, x_max=0, pix_x=pixel_x, pix_y=pixel_y, ) assert np.sum(pred) != 0 """Then check helper function gives the same answer""" shower = ReconstructedGeometryContainer() shower.is_valid = True shower.alt = 0 * u.deg shower.az = 0 * u.deg shower.core_x = 0 * u.m shower.core_y = 100 * u.m shower.h_max = 300 + 93 * np.log10(1) energy = ReconstructedEnergyContainer() energy.is_valid = True energy.energy = 1 * u.TeV pred2 = self.impact_reco.get_prediction(1, shower_reco=shower, energy_reco=energy) print(pred, pred2) assert pred.all() == pred2.all()
def predict(self, shower_seed, energy_seed): """Predict method for the ImPACT reconstructor. Used to calculate the reconstructed ImPACT shower geometry and energy. Parameters ---------- shower_seed: ReconstructedShowerContainer Seed shower geometry to be used in the fit energy_seed: ReconstructedEnergyContainer Seed energy to be used in fit Returns ------- ReconstructedShowerContainer, ReconstructedEnergyContainer: """ self.reset_interpolator() horizon_seed = SkyCoord(az=shower_seed.az, alt=shower_seed.alt, frame=AltAz()) nominal_seed = horizon_seed.transform_to(self.nominal_frame) source_x = nominal_seed.fov_lon.to_value(u.rad) source_y = nominal_seed.fov_lat.to_value(u.rad) ground = GroundFrame(x=shower_seed.core_x, y=shower_seed.core_y, z=0 * u.m) tilted = ground.transform_to( TiltedGroundFrame(pointing_direction=self.array_direction)) tilt_x = tilted.x.to(u.m).value tilt_y = tilted.y.to(u.m).value zenith = 90 * u.deg - self.array_direction.alt seeds = spread_line_seed( self.hillas_parameters, self.tel_pos_x, self.tel_pos_y, source_x, source_y, tilt_x, tilt_y, energy_seed.energy.value, shift_frac=[1], )[0] # Perform maximum likelihood fit fit_params, errors, like = self.minimise( params=seeds[0], step=seeds[1], limits=seeds[2], minimiser_name=self.minimiser_name, ) # Create a container class for reconstructed shower shower_result = ReconstructedGeometryContainer() # Convert the best fits direction and core to Horizon and ground systems and # copy to the shower container nominal = SkyCoord( fov_lon=fit_params[0] * u.rad, fov_lat=fit_params[1] * u.rad, frame=self.nominal_frame, ) horizon = nominal.transform_to(AltAz()) shower_result.alt, shower_result.az = horizon.alt, horizon.az tilted = TiltedGroundFrame( x=fit_params[2] * u.m, y=fit_params[3] * u.m, pointing_direction=self.array_direction, ) ground = project_to_ground(tilted) shower_result.core_x = ground.x shower_result.core_y = ground.y shower_result.is_valid = True # Currently no errors not available to copy NaN shower_result.alt_uncert = np.nan shower_result.az_uncert = np.nan shower_result.core_uncert = np.nan # Copy reconstructed Xmax shower_result.h_max = fit_params[5] * self.get_shower_max( fit_params[0], fit_params[1], fit_params[2], fit_params[3], zenith.to(u.rad).value, ) shower_result.h_max *= np.cos(zenith) shower_result.h_max_uncert = errors[5] * shower_result.h_max shower_result.goodness_of_fit = like # Create a container class for reconstructed energy energy_result = ReconstructedEnergyContainer() # Fill with results energy_result.energy = fit_params[4] * u.TeV energy_result.energy_uncert = errors[4] * u.TeV energy_result.is_valid = True return shower_result, energy_result