Ejemplo n.º 1
0
    def get_prediction(self, tel_id, shower_reco, energy_reco):

        horizon_seed = HorizonFrame(az=shower_reco.az, alt=shower_reco.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=horizon_seed))
        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value

        ground = GroundFrame(x=shower_reco.core_x, y=shower_reco.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
        azimuth = self.array_direction.az

        x_max = shower_reco.h_max / np.cos(zenith)

        # Calculate expected Xmax given this energy
        x_max_exp = guess_shower_depth(energy_reco.energy)

        # Convert to binning of Xmax, addition of 100 can probably be removed
        x_max_bin = x_max - x_max_exp

        # Check for range
        if x_max_bin > 250 * (u.g*u.cm**-2):
            x_max_bin = 250 * (u.g*u.cm**-2)
        if x_max_bin < -250 * (u.g*u.cm**-2):
            x_max_bin = -250 * (u.g*u.cm**-2)

        x_max_bin = x_max_bin.value

        impact = np.sqrt(pow(self.tel_pos_x[tel_id] - tilt_x, 2) +
                         pow(self.tel_pos_y[tel_id] - tilt_y, 2))

        phi = np.arctan2( (self.tel_pos_y[tel_id] - tilt_y),
                          (self.tel_pos_x[tel_id] - tilt_x))

        pix_x_rot, pix_y_rot = self.rotate_translate(self.pixel_x[tel_id]
                                                     * -1,
                                                     self.pixel_y[tel_id],
                                                     source_x,
                                                     source_y, phi)

        prediction = self.image_prediction(self.type[tel_id],
                                           (90 * u.deg) - shower_reco.alt,
                                           shower_reco.az,
                                           energy_reco.energy.value,
                                           impact, x_max_bin,
                                           pix_x_rot * (180 / math.pi),
                                           pix_y_rot * (180 / math.pi))

        prediction *= self.scale[self.type[tel_id]]
        #prediction *= self.pixel_area[tel_id]

        prediction[prediction < 0] = 0
        prediction[np.isnan(prediction)] = 0

        return prediction
Ejemplo n.º 2
0
    def get_prediction(self, tel_id, shower_reco, energy_reco):

        horizon_seed = HorizonFrame(az=shower_reco.az, alt=shower_reco.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=horizon_seed))
        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value

        ground = GroundFrame(x=shower_reco.core_x,
                             y=shower_reco.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

        x_max = shower_reco.h_max / np.cos(zenith)

        # Calculate expected Xmax given this energy
        x_max_exp = guess_shower_depth(energy_reco.energy)

        # Convert to binning of Xmax, addition of 100 can probably be removed
        x_max_bin = x_max - x_max_exp

        # Check for range
        if x_max_bin > 250 * (u.g * u.cm**-2):
            x_max_bin = 250 * (u.g * u.cm**-2)
        if x_max_bin < -250 * (u.g * u.cm**-2):
            x_max_bin = -250 * (u.g * u.cm**-2)

        x_max_bin = x_max_bin.value

        impact = np.sqrt(
            pow(self.tel_pos_x[tel_id] - tilt_x, 2) +
            pow(self.tel_pos_y[tel_id] - tilt_y, 2))

        phi = np.arctan2((self.tel_pos_y[tel_id] - tilt_y),
                         (self.tel_pos_x[tel_id] - tilt_x))

        pix_x_rot, pix_y_rot = self.rotate_translate(self.pixel_x[tel_id] * -1,
                                                     self.pixel_y[tel_id],
                                                     source_x, source_y, phi)

        prediction = self.image_prediction(self.type[tel_id],
                                           (90 * u.deg) - shower_reco.alt,
                                           shower_reco.az,
                                           energy_reco.energy.value, impact,
                                           x_max_bin,
                                           pix_x_rot * (180 / math.pi),
                                           pix_y_rot * (180 / math.pi))

        prediction *= self.scale[self.type[tel_id]]
        # prediction *= self.pixel_area[tel_id]

        prediction[prediction < 0] = 0
        prediction[np.isnan(prediction)] = 0

        return prediction
Ejemplo n.º 3
0
def sky_to_camera(alt, az, focal, pointing_alt, pointing_az):
    """
    Coordinate transform from aky position (alt, az) (in angles) to camera coordinates (x, y) in distance
    Parameters
    ----------
    alt: astropy Quantity
    az: astropy Quantity
    focal: astropy Quantity
    pointing_alt: pointing altitude in angle unit
    pointing_az: pointing altitude in angle unit

    Returns
    -------

    """
    pointing_direction = HorizonFrame(alt=pointing_alt, az=pointing_az)

    event_direction = HorizonFrame(alt=alt, az=az)
    nom_frame = NominalFrame(array_direction=pointing_direction,
                             pointing_direction=pointing_direction)

    event_dir_nom = event_direction.transform_to(nom_frame)

    camera_pos = NominalFrame(
        pointing_direction=pointing_direction,
        x=event_dir_nom.x.to(u.rad).value * focal,
        y=event_dir_nom.y.to(u.rad).value * focal,
    )

    # return focal * (event_dir_nom.x.to(u.rad).value, event_dir_nom.y.to(u.rad).value)
    return camera_pos
Ejemplo n.º 4
0
    def get_position_in_cam(dir_alt, dir_az, event, tel_id):
        """
        transform position in HorizonFrame to CameraFrame

        Parameters
        ----------
        dir_alt : direction altitude
        dir_az : direction azimuth
        event : event data container
        tel_id : telescope ID

        Returns
        -------
        cam_coord : position in camera of telescope tel_id
        """

        # pointing direction of telescope
        pointing_az = event.mc.tel[tel_id].azimuth_raw * u.rad
        pointing_alt = event.mc.tel[tel_id].altitude_raw * u.rad

        pointing = SkyCoord(alt=pointing_alt, az=pointing_az, frame='altaz')

        focal_length = event.inst.subarray.tel[tel_id].\
            optics.equivalent_focal_length

        cf = CameraFrame(focal_length=focal_length,
                         array_direction=pointing,
                         pointing_direction=pointing)

        # direction of event
        direction = HorizonFrame(alt=dir_alt, az=dir_az)
        cam_coord = direction.transform_to(cf)

        return cam_coord
Ejemplo n.º 5
0
    def draw_tilted_surface(self, shower_seed, energy_seed,
                            bins=50, core_range=100 * u.m):
        """
        Simple reconstruction for evaluating the likelihood in a grid across the 
        nominal system, fixing all values but the core position of the gamma rays. 
        Useful for checking the reconstruction performance of the algorithm
        
        Parameters
        ----------
        shower_seed: ReconstructedShowerContainer
            Best fit ImPACT shower geometry 
        energy_seed: ReconstructedEnergyContainer
            Best fit ImPACT energy
        bins: int
            Number of bins in surface evaluation
        nominal_range: Quantity
            Range over which to create likelihood surface

        Returns
        -------
        ndarray, ndarray, ndarray: 
        Bin centres in X and Y coordinates and the values of the likelihood at each 
        position
        """
        horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=self.array_direction))

        source_x = nominal_seed.x[0].to(u.rad).value
        source_y = nominal_seed.y[0].to(u.rad).value

        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)
        tilt_y = tilted.y.to(u.m)

        x_ground_list = np.linspace(tilt_x - core_range, tilt_x + core_range, num=bins)
        y_ground_list = np.linspace(tilt_y - core_range, tilt_y + core_range, num=bins)
        w = np.zeros([bins, bins])
        zenith = 90*u.deg - self.array_direction.alt

        for xb in range(bins):
            for yb in range(bins):
                x_max_scale = shower_seed.h_max / \
                              self.get_shower_max(source_x,
                                                  source_y,
                                                  x_ground_list[xb].value,
                                                  y_ground_list[yb].value,
                                                  zenith.to(u.rad).value)

                w[xb][yb] =  self.get_likelihood(source_x,
                                                 source_y,
                                                 x_ground_list[xb].value,
                                                 y_ground_list[yb].value,
                                                 energy_seed.energy.value, x_max_scale)
        return x_ground_list, y_ground_list, w
Ejemplo n.º 6
0
    def get_prediction(self, tel_id, shower_reco, energy_reco):

        horizon_seed = HorizonFrame(az=shower_reco.az, alt=shower_reco.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=horizon_seed))
        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value

        print(self.array_direction[0])
        ground = GroundFrame(x=shower_reco.core_x,
                             y=shower_reco.core_y, z=0 * u.m)
        tilted = ground.transform_to(
            TiltedGroundFrame(
                pointing_direction=HorizonFrame(alt=self.array_direction[0],
                                                az=self.array_direction[1])
            )
        )
        tilt_x = tilted.x.to(u.m).value
        tilt_y = tilted.y.to(u.m).value

        zenith = 90 * u.deg - self.array_direction[0]
        azimuth = self.array_direction[1]

        x_max_exp = 300 + 93 * np.log10(energy_reco.energy.value)
        x_max = shower_reco.h_max / np.cos(zenith)

        # Convert to binning of Xmax, addition of 100 can probably be removed
        x_max_bin = x_max.value - x_max_exp
        if x_max_bin > 100:
            x_max_bin = 100
        if x_max_bin < -100:
            x_max_bin = -100

        impact = np.sqrt(pow(self.tel_pos_x[tel_id] - tilt_x, 2) +
                         pow(self.tel_pos_y[tel_id] - tilt_y, 2))

        phi = np.arctan2( (self.tel_pos_y[tel_id] - tilt_y),
                          (self.tel_pos_x[tel_id] - tilt_x))

        pix_x_rot, pix_y_rot = self.rotate_translate(self.pixel_x[tel_id]
                                                     * -1,
                                                     self.pixel_y[tel_id],
                                                     source_x,
                                                     source_y, phi)

        prediction = self.image_prediction(self.type[tel_id],
                                           20 * u.deg,
                                           0 * u.deg,
                                           energy_reco.energy.value,
                                           impact, x_max_bin,
                                           pix_x_rot * (180 / math.pi),
                                           pix_y_rot * (180 / math.pi))

        prediction *= self.scale[self.type[tel_id]]
        prediction[prediction < 0] = 0
        prediction[np.isnan(prediction)] = 0

        return prediction
Ejemplo n.º 7
0
    def get_prediction(self, tel_id, shower_reco, energy_reco):

        horizon_seed = HorizonFrame(az=shower_reco.az, alt=shower_reco.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=horizon_seed))
        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value

        print(self.array_direction[0])
        ground = GroundFrame(x=shower_reco.core_x,
                             y=shower_reco.core_y,
                             z=0 * u.m)
        tilted = ground.transform_to(
            TiltedGroundFrame(pointing_direction=HorizonFrame(
                alt=self.array_direction[0], az=self.array_direction[1])))
        tilt_x = tilted.x.to(u.m).value
        tilt_y = tilted.y.to(u.m).value

        zenith = 90 * u.deg - self.array_direction[0]
        azimuth = self.array_direction[1]

        x_max_exp = 300 + 93 * np.log10(energy_reco.energy.value)
        x_max = shower_reco.h_max / np.cos(zenith)

        # Convert to binning of Xmax, addition of 100 can probably be removed
        x_max_bin = x_max.value - x_max_exp
        if x_max_bin > 100:
            x_max_bin = 100
        if x_max_bin < -100:
            x_max_bin = -100

        impact = np.sqrt(
            pow(self.tel_pos_x[tel_id] - tilt_x, 2) +
            pow(self.tel_pos_y[tel_id] - tilt_y, 2))

        phi = np.arctan2((self.tel_pos_y[tel_id] - tilt_y),
                         (self.tel_pos_x[tel_id] - tilt_x))

        pix_x_rot, pix_y_rot = self.rotate_translate(self.pixel_x[tel_id] * -1,
                                                     self.pixel_y[tel_id],
                                                     source_x, source_y, phi)

        prediction = self.image_prediction(self.type[tel_id], 20 * u.deg,
                                           0 * u.deg, energy_reco.energy.value,
                                           impact, x_max_bin,
                                           pix_x_rot * (180 / math.pi),
                                           pix_y_rot * (180 / math.pi))

        prediction *= self.scale[self.type[tel_id]]
        prediction[prediction < 0] = 0
        prediction[np.isnan(prediction)] = 0

        return prediction
Ejemplo n.º 8
0
def get_event_pos_in_camera(event, tel):
    """
    Return the position of the source in the camera frame
    Parameters
    ----------
    event: `ctapipe.io.containers.DataContainer`
    tel: `ctapipe.instruement.telescope.TelescopeDescription`

    Returns
    -------
    (x, y) (float, float): position in the camera
    """
    array_pointing = HorizonFrame(alt=event.mcheader.run_array_direction[1],
                              az=event.mcheader.run_array_direction[0])
    event_direction = HorizonFrame(alt=event.mc.alt.to(u.rad),
                               az=event.mc.az.to(u.rad))

    nom_frame = NominalFrame(array_direction=array_pointing,
                         pointing_direction=array_pointing)

    event_dir_nom = event_direction.transform_to(nom_frame)
    focal = tel.optics.equivalent_focal_length
    return focal * (event_dir_nom.x.to(u.rad).value, event_dir_nom.y.to(u.rad).value)
Ejemplo n.º 9
0
    def predict(self, shower_seed, energy_seed):
        """
        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:
        Reconstructed ImPACT shower geometry and energy
        """

        horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt)
        nominal_seed = horizon_seed.transform_to(NominalFrame(
            array_direction=self.array_direction))

        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value
        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

        if len(self.hillas_parameters) > 3:
            shift = [1]
        else:
            shift = [1.5, 1, 0.5, 0, -0.5, -1, -1.5]

        seed_list = spread_line_seed(self.hillas_parameters,
                                     self.tel_pos_x, self.tel_pos_y,
                                     source_x[0], source_y[0], tilt_x, tilt_y,
                                     energy_seed.energy.value,
                                     shift_frac = shift)

        chosen_seed = self.choose_seed(seed_list)
        # Perform maximum likelihood fit
        fit_params, errors, like = self.minimise(params=chosen_seed[0],
                                                 step=chosen_seed[1],
                                                 limits=chosen_seed[2],
                                                 minimiser_name=self.minimiser_name)

        # Create a container class for reconstructed shower
        shower_result = ReconstructedShowerContainer()

        # Convert the best fits direction and core to Horizon and ground systems and
        # copy to the shower container
        nominal = NominalFrame(x=fit_params[0] * u.rad,
                               y=fit_params[1] * u.rad,
                               array_direction=self.array_direction)
        horizon = nominal.transform_to(HorizonFrame())

        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 availible 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
Ejemplo n.º 10
0
    def predict(self, shower_seed, energy_seed):
        """
        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:
        Reconstructed ImPACT shower geometry and energy        
        """

        horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=self.array_direction))
        print(nominal_seed)
        print(horizon_seed)
        print(self.array_direction)

        source_x = nominal_seed.x[0].to(u.rad).value
        source_y = nominal_seed.y[0].to(u.rad).value

        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

        lower_en_limit = energy_seed.energy * 0.5
        en_seed = energy_seed.energy
        if lower_en_limit < 0.04 * u.TeV:
            lower_en_limit = 0.04 * u.TeV
            en_seed = 0.041 * u.TeV

        seed = (source_x, source_y, tilt_x, tilt_y, en_seed.value, 0.8)
        step = (0.001, 0.001, 10, 10, en_seed.value * 0.1, 0.1)
        limits = ((source_x - 0.01, source_x + 0.01), (source_y - 0.01,
                                                       source_y + 0.01),
                  (tilt_x - 100, tilt_x + 100), (tilt_y - 100, tilt_y + 100),
                  (lower_en_limit.value, en_seed.value * 2), (0.5, 2))

        fit_params, errors = self.minimise(params=seed,
                                           step=step,
                                           limits=limits,
                                           minimiser_name=self.minimiser_name)

        # container class for reconstructed showers '''
        shower_result = ReconstructedShowerContainer()

        nominal = NominalFrame(x=fit_params[0] * u.rad,
                               y=fit_params[1] * u.rad,
                               array_direction=self.array_direction)
        horizon = nominal.transform_to(HorizonFrame())

        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

        shower_result.alt_uncert = np.nan
        shower_result.az_uncert = np.nan
        shower_result.core_uncert = np.nan

        zenith = 90 * u.deg - self.array_direction.alt
        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_uncert = errors[5] * shower_result.h_max

        shower_result.goodness_of_fit = np.nan
        shower_result.tel_ids = list(self.image.keys())

        energy_result = ReconstructedEnergyContainer()
        energy_result.energy = fit_params[4] * u.TeV
        energy_result.energy_uncert = errors[4] * u.TeV
        energy_result.is_valid = True
        energy_result.tel_ids = list(self.image.keys())
        # Return interesting stuff

        return shower_result, energy_result
Ejemplo n.º 11
0
    def predict(self, shower_seed, energy_seed):
        """

        Parameters
        ----------
        source_x: float
            Initial guess of source position in the nominal frame
        source_y: float
            Initial guess of source position in the nominal frame
        core_x: float
            Initial guess of the core position in the tilted system
        core_y: float
            Initial guess of the core position in the tilted system
        energy: float
            Initial guess of energy

        Returns
        -------
        Shower object with fit results
        """
        horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=self.array_direction))

        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value

        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

        lower_en_limit = energy_seed.energy * 0.1
        if lower_en_limit < 0.04 * u.TeV:
            lower_en_limit = 0.04 * u.TeV
        # Create Minuit object with first guesses at parameters, strip away the
        # units as Minuit doesnt like them
        min = Minuit(self.get_likelihood,
                     print_level=1,
                     source_x=source_x,
                     error_source_x=0.01 / 57.3,
                     fix_source_x=False,
                     limit_source_x=(source_x - 0.5 / 57.3,
                                     source_x + 0.5 / 57.3),
                     source_y=source_y,
                     error_source_y=0.01 / 57.3,
                     fix_source_y=False,
                     limit_source_y=(source_y - 0.5 / 57.3,
                                     source_y + 0.5 / 57.3),
                     core_x=tilt_x,
                     error_core_x=10,
                     limit_core_x=(tilt_x - 200, tilt_x + 200),
                     core_y=tilt_y,
                     error_core_y=10,
                     limit_core_y=(tilt_y - 200, tilt_y + 200),
                     energy=energy_seed.energy.value,
                     error_energy=energy_seed.energy.value * 0.05,
                     limit_energy=(lower_en_limit.value,
                                   energy_seed.energy.value * 10.),
                     x_max_scale=1,
                     error_x_max_scale=0.1,
                     limit_x_max_scale=(0.5, 2),
                     fix_x_max_scale=False,
                     errordef=1)

        min.tol *= 1000
        min.strategy = 0

        # Perform minimisation
        migrad = min.migrad()
        fit_params = min.values
        errors = min.errors
        #    print(migrad)
        #    print(min.minos())

        # container class for reconstructed showers '''
        shower_result = ReconstructedShowerContainer()

        nominal = NominalFrame(x=fit_params["source_x"] * u.rad,
                               y=fit_params["source_y"] * u.rad,
                               array_direction=self.array_direction)
        horizon = nominal.transform_to(HorizonFrame())

        shower_result.alt, shower_result.az = horizon.alt, horizon.az
        tilted = TiltedGroundFrame(x=fit_params["core_x"] * u.m,
                                   y=fit_params["core_y"] * 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

        shower_result.alt_uncert = np.nan
        shower_result.az_uncert = np.nan
        shower_result.core_uncert = np.nan
        zenith = 90 * u.deg - self.array_direction[0]
        shower_result.h_max = fit_params["x_max_scale"] * \
            self.get_shower_max(fit_params["source_x"],
                                fit_params["source_y"],
                                fit_params["core_x"],
                                fit_params["core_y"],
                                zenith.to(u.rad).value)
        shower_result.h_max_uncert = errors["x_max_scale"] * shower_result.h_max
        shower_result.goodness_of_fit = np.nan
        shower_result.tel_ids = list(self.image.keys())

        energy_result = ReconstructedEnergyContainer()
        energy_result.energy = fit_params["energy"] * u.TeV
        energy_result.energy_uncert = errors["energy"] * u.TeV
        energy_result.is_valid = True
        energy_result.tel_ids = list(self.image.keys())
        # Return interesting stuff

        return shower_result, energy_result
Ejemplo n.º 12
0
    def predict(self, shower_seed, energy_seed):
        """
        
        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:
        Reconstructed ImPACT shower geometry and energy
        
        """
        horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt)
        nominal_seed = horizon_seed.transform_to(NominalFrame(array_direction=self.array_direction))
        print(nominal_seed)
        print(horizon_seed)
        print(self.array_direction)

        source_x = nominal_seed.x[0].to(u.rad).value
        source_y = nominal_seed.y[0].to(u.rad).value

        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

        lower_en_limit = energy_seed.energy * 0.5
        en_seed =  energy_seed.energy
        if lower_en_limit < 0.04 * u.TeV:
            lower_en_limit = 0.04 * u.TeV
            en_seed = 0.041 * u.TeV

        seed = (source_x, source_y, tilt_x,
                tilt_y, en_seed.value, 0.8)
        step = (0.001, 0.001, 10, 10, en_seed.value*0.1, 0.1)
        limits = ((source_x-0.01, source_x+0.01),
                  (source_y-0.01, source_y+0.01),
                  (tilt_x-100, tilt_x+100),
                  (tilt_y-100, tilt_y+100),
                  (lower_en_limit.value, en_seed.value*2),
                  (0.5,2))

        fit_params, errors = self.minimise(params=seed, step=step, limits=limits,
                                             minimiser_name=self.minimiser_name)

        # container class for reconstructed showers '''
        shower_result = ReconstructedShowerContainer()

        nominal = NominalFrame(x=fit_params[0] * u.rad,
                               y=fit_params[1] * u.rad,
                               array_direction=self.array_direction)
        horizon = nominal.transform_to(HorizonFrame())

        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

        shower_result.alt_uncert = np.nan
        shower_result.az_uncert = np.nan
        shower_result.core_uncert = np.nan

        zenith = 90*u.deg - self.array_direction.alt
        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_uncert = errors[5] * shower_result.h_max

        shower_result.goodness_of_fit = np.nan
        shower_result.tel_ids = list(self.image.keys())

        energy_result = ReconstructedEnergyContainer()
        energy_result.energy = fit_params[4] * u.TeV
        energy_result.energy_uncert = errors[4] * u.TeV
        energy_result.is_valid = True
        energy_result.tel_ids = list(self.image.keys())
        # Return interesting stuff

        return shower_result, energy_result
Ejemplo n.º 13
0
    def predict(self, shower_seed, energy_seed):
        """

        Parameters
        ----------
        source_x: float
            Initial guess of source position in the nominal frame
        source_y: float
            Initial guess of source position in the nominal frame
        core_x: float
            Initial guess of the core position in the tilted system
        core_y: float
            Initial guess of the core position in the tilted system
        energy: float
            Initial guess of energy

        Returns
        -------
        Shower object with fit results
        """
        horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt)
        nominal_seed = horizon_seed.transform_to(
            NominalFrame(array_direction=self.array_direction)
        )

        source_x = nominal_seed.x.to(u.rad).value
        source_y = nominal_seed.y.to(u.rad).value

        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

        lower_en_limit = energy_seed.energy * 0.1
        if lower_en_limit < 0.04 * u.TeV:
            lower_en_limit = 0.04 * u.TeV
        # Create Minuit object with first guesses at parameters, strip away the
        # units as Minuit doesnt like them
        min = Minuit(self.get_likelihood,
                     print_level=1,
                     source_x=source_x,
                     error_source_x=0.01 / 57.3,
                     fix_source_x=False,
                     limit_source_x=(source_x - 0.5 / 57.3,
                                     source_x + 0.5 / 57.3),
                     source_y=source_y,
                     error_source_y=0.01 / 57.3,
                     fix_source_y=False,
                     limit_source_y=(source_y - 0.5 / 57.3,
                                     source_y + 0.5 / 57.3),
                     core_x=tilt_x,
                     error_core_x=10,
                     limit_core_x=(tilt_x - 200, tilt_x + 200),
                     core_y=tilt_y,
                     error_core_y=10,
                     limit_core_y=(tilt_y - 200, tilt_y + 200),
                     energy=energy_seed.energy.value,
                     error_energy=energy_seed.energy.value * 0.05,
                     limit_energy=(lower_en_limit.value,
                                   energy_seed.energy.value * 10.),
                     x_max_scale=1, error_x_max_scale=0.1,
                     limit_x_max_scale=(0.5, 2),
                     fix_x_max_scale=False,
                     errordef=1)

        min.tol *= 1000
        min.strategy = 0

        # Perform minimisation
        migrad = min.migrad()
        fit_params = min.values
        errors = min.errors
    #    print(migrad)
    #    print(min.minos())

        # container class for reconstructed showers '''
        shower_result = ReconstructedShowerContainer()

        nominal = NominalFrame(x=fit_params["source_x"] * u.rad,
                               y=fit_params["source_y"] * u.rad,
                               array_direction=self.array_direction)
        horizon = nominal.transform_to(HorizonFrame())

        shower_result.alt, shower_result.az = horizon.alt, horizon.az
        tilted = TiltedGroundFrame(x=fit_params["core_x"] * u.m,
                                   y=fit_params["core_y"] * 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

        shower_result.alt_uncert = np.nan
        shower_result.az_uncert = np.nan
        shower_result.core_uncert = np.nan
        zenith = 90 * u.deg - self.array_direction[0]
        shower_result.h_max = fit_params["x_max_scale"] * \
            self.get_shower_max(fit_params["source_x"],
                                fit_params["source_y"],
                                fit_params["core_x"],
                                fit_params["core_y"],
                                zenith.to(u.rad).value)
        shower_result.h_max_uncert = errors["x_max_scale"] * shower_result.h_max
        shower_result.goodness_of_fit = np.nan
        shower_result.tel_ids = list(self.image.keys())

        energy_result = ReconstructedEnergyContainer()
        energy_result.energy = fit_params["energy"] * u.TeV
        energy_result.energy_uncert = errors["energy"] * u.TeV
        energy_result.is_valid = True
        energy_result.tel_ids = list(self.image.keys())
        # Return interesting stuff

        return shower_result, energy_result