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()
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
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
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
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
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
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
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)
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
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 = _
def __init__(self, atmosphere_profile_name): self.thickness_profile, self.altitude_profile = \ get_atmosphere_profile_functions(atmosphere_profile_name)
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)
def __init__(self, atmosphere_profile_name): self.thickness_profile, self.altitude_profile = \ get_atmosphere_profile_functions(atmosphere_profile_name)