Esempio n. 1
0
def main(input_files, output, site, complementary, label):

    bins, bin_center, bin_widths = make_energy_bins(e_min=0.003 * u.TeV,
                                                    e_max=330 * u.TeV,
                                                    bins=10)

    for input, color, l in zip(input_files, color_cycle, label):
        df = fact.io.read_data(
            input,
            key='array_events',
            columns=['mc_energy', 'h_max_prediction', 'mc_x_max']).dropna()
        thickness, altitude = get_atmosphere_profile_functions(site)

        mc_h_max = altitude(df.mc_x_max.values * u.Unit('g/cm^2')).value
        y = mc_h_max - df.h_max_prediction
        x = df.mc_energy.values

        b_50, bin_edges, binnumber = binned_statistic(x,
                                                      y,
                                                      statistic='median',
                                                      bins=bins)

        bin_centers = np.sqrt(bin_edges[1:] * bin_edges[:-1])
        plt.step(bin_centers, b_50, lw=2, color=color, label=l, where='mid')

    plt.xscale('log')
    # plt.yscale('log')
    plt.ylabel('Distance to true H max  / meter')
    plt.xlabel(r'True Energy / TeV ')
    plt.legend()
    plt.tight_layout()
    if output:
        plt.savefig(output)
    else:
        plt.show()
Esempio n. 2
0
    def __init__(
        self,
        root_dir=".",
        minimiser="minuit",
        prior="",
        template_scale=1.0,
        xmax_offset=0,
        use_time_gradient=False,
    ):

        # First we create a dictionary of image template interpolators
        # for each telescope type
        self.root_dir = root_dir
        self.priors = prior
        self.minimiser_name = minimiser

        self.file_names = {
            "CHEC":
            ["GCT_05deg_ada.template.gz", "GCT_05deg_time.template.gz"],
            "LSTCam": ["LST_05deg.template.gz", "LST_05deg_time.template.gz"],
            "NectarCam":
            ["MST_05deg.template.gz", "MST_05deg_time.template.gz"],
            "FlashCam": ["MST_xm_full.fits"],
        }

        # We also need a conversion function from height above ground to
        # depth of maximum To do this we need the conversion table from CORSIKA
        (
            self.thickness_profile,
            self.altitude_profile,
        ) = get_atmosphere_profile_functions("paranal", with_units=False)

        # Next we need the position, area and amplitude from each pixel in the event
        # making this a class member makes passing them around much easier

        self.pixel_x, self.pixel_y = None, None
        self.image, self.time = None, None

        self.tel_types, self.tel_id = None, None

        # We also need telescope positions
        self.tel_pos_x, self.tel_pos_y = None, None

        # And the peak of the images
        self.peak_x, self.peak_y, self.peak_amp = None, None, None
        self.hillas_parameters, self.ped = None, None

        self.prediction = dict()
        self.time_prediction = dict()

        self.array_direction = None
        self.array_return = False
        self.nominal_frame = None

        # For now these factors are required to fix problems in templates
        self.template_scale = template_scale
        self.xmax_offset = xmax_offset
        self.use_time_gradient = use_time_gradient
Esempio n. 3
0
def plot_h_max(reconstructed_events,
               site='paranal',
               colormap=default_cmap,
               color=main_color,
               ax=None):
    df = reconstructed_events
    df = df.loc[df.mc_x_max > 0]
    thickness, altitude = get_atmosphere_profile_functions(site)

    mc_h_max = altitude(df.mc_x_max.clip(upper=1020).values * u.Unit('g/cm^2'))

    bins, bin_center, bin_widths = make_default_cta_binning(
        e_min=0.01 * u.TeV,
        e_max=200 * u.TeV,
    )
    x = df.mc_energy.values

    b_50, bin_edges, binnumber = binned_statistic(x,
                                                  df.h_max,
                                                  statistic='median',
                                                  bins=bins)
    b_84, _, _ = binned_statistic(x,
                                  df.h_max,
                                  statistic=lambda x: np.percentile(x, q=[84]),
                                  bins=bins)
    b_16, _, _ = binned_statistic(x,
                                  df.h_max,
                                  statistic=lambda x: np.percentile(x, q=[16]),
                                  bins=bins)

    log_emin, log_emax = np.log10(0.007), np.log10(300)

    if not ax:
        fig, ax = plt.subplots(1, 1)

    im = ax.hexbin(x,
                   mc_h_max,
                   xscale='log',
                   extent=(log_emin, log_emax, 0, 17500),
                   cmap=colormap,
                   norm=PowerNorm(0.5))
    add_colorbar_to_figure(im, fig, ax, label='Counts')

    ax.hlines(b_50[:-1],
              bins[:-2],
              bins[1:-1],
              lw=2,
              color=color,
              label='Median Prediction')
    ax.fill_between(bins[:-1], b_16, b_84, alpha=0.3, color=color, step='post')

    ax.set_xscale('log')
    ax.set_ylabel('Max Height / m')
    ax.set_xlabel('True Energy / TeV')
    ax.legend(framealpha=0.0)
    ax.set_xlim([0.007, 300])
    plt.tight_layout(pad=0, rect=(0, 0, 1.003, 1))
    return ax
Esempio n. 4
0
    def __init__(self, root_dir=".", minimiser="minuit", prior=""):

        # First we create a dictionary of image template interpolators
        # for each telescope type
        self.root_dir = root_dir
        self.prediction = dict()

        self.file_names = {"CHEC": "GCT_xm_full.fits", "LSTCam": "LST_xm_full.fits",
                           "NectarCam": "MST_xm_full.fits",
                           "FlashCam": "MST_xm_full.fits"}

        # We also need a conversion function from height above ground to
        # depth of maximum To do this we need the conversion table from CORSIKA
        self.thickness_profile, self.altitude_profile = \
            get_atmosphere_profile_functions('paranal')

        # For likelihood calculation we need the with of the
        # pedestal distribution for each pixel
        # currently this is not availible from the calibration,
        # so for now lets hard code it in a dict
        self.ped_table = {"LSTCam": 1.3,
                          "NectarCam": 2.0,
                          "FlashCam": 2.3,
                          "CHEC": 1.3}
        self.spe = 0.5  # Also hard code single p.e. distribution width

        # Also we need to scale the impact_reco templates a bit, this will be
        #  fixed later
        self.scale = {"LSTCam": 1.3, "NectarCam": 1.1,
                      "FlashCam": 1.4, "CHEC": 1.0}  # * 1.36}

        self.last_image = dict()
        self.last_point = dict()

        # Next we need the position, area and amplitude from each pixel in the event
        # making this a class member makes passing them around much easier

        self.pixel_x = 0
        self.pixel_y = 0
        self.pixel_area = 0
        self.image = 0
        self.tel_type = ("LST")
        # We also need telescope positions
        self.tel_pos_x = 0
        self.tel_pos_y = 0
        # And the peak of the images
        self.peak_x = 0
        self.peak_y = 0
        self.peak_amp = 0
        self.hillas = 0

        self.ped = dict()

        self.array_direction = 0
        self.minimiser_name = minimiser

        self.array_return = False
        self.priors = prior
Esempio n. 5
0
    def __init__(self, config=None, parent=None, **kwargs):
        """
        Weighting must be a function similar to the weight_konrad already implemented
        """
        super().__init__(config=config, parent=parent, **kwargs)

        # We need a conversion function from height above ground to depth of maximum
        # To do this we need the conversion table from CORSIKA
        _ = get_atmosphere_profile_functions(self.atmosphere_profile_name)
        self.thickness_profile, self.altitude_profile = _

        # other weighting schemes can be implemented. just add them as additional methods
        if self.weighting == "Konrad":
            self._weight_method = self.weight_konrad
Esempio n. 6
0
    def __init__(self, root_dir=".", minimiser="minuit", prior=""):

        # First we create a dictionary of image template interpolators
        # for each telescope type
        self.root_dir = root_dir
        self.prediction = dict()

        self.file_names = {"GATE":"GCT_xm_full.fits", "LSTCam":"LST_xm_full.fits",
                           "NectarCam":"MST_xm_full.fits", "FlashCam":"MST_xm_full.fits"}

        # We also need a conversion function from height above ground to depth of maximum
        # To do this we need the conversion table from CORSIKA
        self.thickness_profile, self.altitude_profile = \
            get_atmosphere_profile_functions('paranal')

        # For likelihood calculation we need the with of the pedestal distribution for each pixel
        # currently this is not availible from the calibration, so for now lets hard code it in a dict
        self.ped_table = {"LSTCam": 1.3, "NectarCam": 2.0, "FlashCam": 2.3,"GATE": 1.3}
        self.spe = 0.5 # Also hard code single p.e. distribution width

        # Also we need to scale the impact_reco templates a bit, this will be fixed later
        self.scale = {"LSTCam": 1.3, "NectarCam": 1.1, "FlashCam": 1.4, "GATE": 1.0}

        self.last_image = dict()
        self.last_point = dict()

        # Next we need the position, area and amplitude from each pixel in the event
        # making this a class member makes passing them around much easier

        self.pixel_x = 0
        self.pixel_y = 0
        self.pixel_area = 0
        self.image = 0
        self.type = ("LST")
        # We also need telescope positions
        self.tel_pos_x = 0
        self.tel_pos_y = 0
        # And the peak of the images
        self.peak_x = 0
        self.peak_y = 0
        self.peak_amp = 0
        self.hillas = 0

        self.ped = dict()

        self.array_direction = 0
        self.minimiser_name = minimiser

        self.array_return = False
        self.priors = prior
Esempio n. 7
0
    def __init__(self, root_dir=".", minimiser="minuit", prior="",
                 template_scale=1., xmax_offset=0, use_time_gradient=False):

        # First we create a dictionary of image template interpolators
        # for each telescope type
        self.root_dir = root_dir
        self.priors = prior
        self.minimiser_name = minimiser

        self.file_names = {"CHEC": ["GCT_05deg_ada.template.gz",
                                    "GCT_05deg_time.template.gz"],
                           "LSTCam": ["LST_05deg.template.gz",
                                      "LST_05deg_time.template.gz"],
                           "NectarCam": ["MST_05deg.template.gz",
                                         "MST_05deg_time.template.gz"],
                           "FlashCam": ["MST_xm_full.fits"]}

        # We also need a conversion function from height above ground to
        # depth of maximum To do this we need the conversion table from CORSIKA
        self.thickness_profile, self.altitude_profile = \
            get_atmosphere_profile_functions('paranal', with_units=False)

        # Next we need the position, area and amplitude from each pixel in the event
        # making this a class member makes passing them around much easier

        self.pixel_x, self.pixel_y = None, None
        self.image, self.time = None, None

        self.tel_types, self.tel_id = None, None

        # We also need telescope positions
        self.tel_pos_x, self.tel_pos_y = None, None

        # And the peak of the images
        self.peak_x, self.peak_y, self.peak_amp = None, None, None
        self.hillas_parameters, self.ped = None, None

        self.prediction = dict()
        self.time_prediction = dict()

        self.array_direction = None
        self.array_return = False

        # For now these factors are required to fix problems in templates
        self.template_scale = template_scale
        self.xmax_offset = xmax_offset
        self.use_time_gradient = use_time_gradient
Esempio n. 8
0
    def __init__(self, atmosphere_profile_name, col_altitude=0, col_thickness=2):
        """
        small class that calculates the height of the shower maximum
        given a parametrisation of the atmosphere
        and certain parameters of the shower itself

        Parameters
        ----------
        atmosphere_profile_name : string
            path to text file that contains a table of the
            atmosphere parameters
        col_altitude : int
            column in the text file that contains the altitude/height
        col_thickness : int
            column in the text file that contains the thickness
        """

        self.thickness_profile, self.altitude_profile = \
            get_atmosphere_profile_functions(atmosphere_profile_name)
Esempio n. 9
0
def plot_h_max_distance(reconstructed_events,
                        site='paranal',
                        colormap=default_cmap,
                        color=main_color,
                        ax=None):
    df = reconstructed_events
    df = df.loc[df.mc_x_max > 0]
    thickness, altitude = get_atmosphere_profile_functions(site)

    mc_h_max = altitude(df.mc_x_max.values * u.Unit('g/cm^2')).value
    y = mc_h_max - df.h_max

    bins, bin_center, bin_widths = make_default_cta_binning(e_min=0.003 *
                                                            u.TeV,
                                                            e_max=330 * u.TeV)
    x = df.mc_energy.values

    b_50, bin_edges, binnumber = binned_statistic(x,
                                                  y,
                                                  statistic='median',
                                                  bins=bins)

    bin_centers = np.sqrt(bin_edges[1:] * bin_edges[:-1])

    log_emin, log_emax = np.log10(bins.min().value), np.log10(bins.max().value)

    if not ax:
        fig, ax = plt.subplots(1, 1)

    im = ax.hexbin(x,
                   y,
                   xscale='log',
                   extent=(log_emin, log_emax, 0.01, 3000),
                   cmap=colormap,
                   norm=PowerNorm(0.5))
    add_colorbar_to_figure(im, fig, ax)
    ax.plot(bin_centers, b_50, lw=2, color=color, label='Median')

    ax.set_xscale('log')
    ax.set_ylabel('Distance to true H max  / meter')
    ax.set_xlabel(r'$E_{True} / TeV$')
    ax.set_xlim([0.007, 300])
    return ax
Esempio n. 10
0
    def __init__(self, atmosphere_profile_name="paranal"):

        # We need a conversion function from height above ground to depth of maximum
        # To do this we need the conversion table from CORSIKA
        _ = get_atmosphere_profile_functions(atmosphere_profile_name)
        self.thickness_profile, self.altitude_profile = _
Esempio n. 11
0
    def __init__(self, atmosphere_profile_name):

        self.thickness_profile, self.altitude_profile = \
            get_atmosphere_profile_functions(atmosphere_profile_name)
Esempio n. 12
0
    def __init__(self, atmosphere_profile_name="paranal"):

        # We need a conversion function from height above ground to depth of maximum
        # To do this we need the conversion table from CORSIKA
        self.thickness_profile, self.altitude_profile = get_atmosphere_profile_functions(
            atmosphere_profile_name)
Esempio n. 13
0
    def __init__(self, atmosphere_profile_name):

        self.thickness_profile, self.altitude_profile = \
            get_atmosphere_profile_functions(atmosphere_profile_name)