This page is a tutorial for the (GammaBayes)[https://github.com/lpin0002/GammaBayes] and the original notebook can be found within the docs/tutorials folder within the GitHub repository.

Binning Schemes with GammaBinning

GammaBayes works primarily with binned event data. In essence, we have a continuous set of energy, longitude, and latitude values that we group into discrete values either due to limitations in the instrument that detected them or for computational efficiency, the latter being the main reason GammaBayes bins the data.

GammaBayes is primarily developed for use of Imaging Atmospheric Cherenkov Telescope arrays (mostly CTAO) which gives reconstructed event data of energy, longitude and latitude values. GammaBinning takes in the axes for these values and provides many handy related utilities which we will look at in this tutorial.

Base use case

The default presumed use case of GammaBinning is that you, the user, have some idea for what the bin centres for your energy, longitude and latitude values like below.

[1]:
import numpy as np
from astropy import units as u

energy_axis     = np.logspace(-1,2, 16)*u.TeV
longitude_axis  = np.linspace(-3, 3, 31)*u.deg
latitude_axis   = np.linspace(-2, 2, 11)*u.deg

We have set our energy axis to be from 0.1 TeV to 100 TeV with 10 bins per decade, our longitude axis to go from -3 to 3 degree in galactic longitude and our latitude axis to go from -2 to 2 degree in galactic latitude.

We then put these into GammaBinning like so.

[2]:
from gammabayes import GammaBinning

binning_geometry = GammaBinning(energy_axis=energy_axis, lon_axis=longitude_axis, lat_axis=latitude_axis)
/Users/lpin0002/anaconda3/envs/testofwest/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

No we will go into the various functions and attributes for this class instance.

GammaBinning attributes

axes

This attribute allow you to extract a list of the axes contained in a GammaBinning instance.

[3]:
binning_geometry.axes
[3]:
[<Quantity [  0.1       ,   0.15848932,   0.25118864,   0.39810717,
              0.63095734,   1.        ,   1.58489319,   2.51188643,
              3.98107171,   6.30957344,  10.        ,  15.84893192,
             25.11886432,  39.81071706,  63.09573445, 100.        ] TeV>,
 <Quantity [-3. , -2.8, -2.6, -2.4, -2.2, -2. , -1.8, -1.6, -1.4, -1.2,
            -1. , -0.8, -0.6, -0.4, -0.2,  0. ,  0.2,  0.4,  0.6,  0.8,
             1. ,  1.2,  1.4,  1.6,  1.8,  2. ,  2.2,  2.4,  2.6,  2.8,
             3. ] deg>,
 <Quantity [-2. , -1.6, -1.2, -0.8, -0.4,  0. ,  0.4,  0.8,  1.2,  1.6,
             2. ] deg>]

lon_res and lat_res

Presuming that the angular axes have linearly separated values lat_res and lon_res allow you to extract the spacing between the bins. Here you can see that we set the spacing between the longitude axis bins to be smaller than the latitude axis bin separation.

[4]:
binning_geometry.lon_res, binning_geometry.lat_res
[4]:
(<Quantity 0.2 deg>, <Quantity 0.4 deg>)

axes_mesh

Gives a mesh grid of all the axis values. If you have axes of size x, y, and z for example then you will get a list of three arrays of size (x, y, z) for the energy, longitude and latitude values respectively.

[5]:
binning_geometry.axes_mesh[0].shape # energy values
[5]:
(16, 31, 11)

axes_dim

Returns the dimensions of the energy, longitude and latitude axes in a tuple

[6]:
binning_geometry.axes_dim
[6]:
(16, 31, 11)

spatial_axes

An attribute that contains a list of the two angular/spatial axes, i.e. [longitude axis, latitude axis]

[7]:
binning_geometry.spatial_axes
[7]:
[<Quantity [-3. , -2.8, -2.6, -2.4, -2.2, -2. , -1.8, -1.6, -1.4, -1.2,
            -1. , -0.8, -0.6, -0.4, -0.2,  0. ,  0.2,  0.4,  0.6,  0.8,
             1. ,  1.2,  1.4,  1.6,  1.8,  2. ,  2.2,  2.4,  2.6,  2.8,
             3. ] deg>,
 <Quantity [-2. , -1.6, -1.2, -0.8, -0.4,  0. ,  0.4,  0.8,  1.2,  1.6,
             2. ] deg>]

spatial_centre

This attribute is the mean of the longitude and latitude axes as a coordinate for use as a ‘centre’. It is not necessarily also a bin coordinate and quite often there are some floating point errors leading to slightly off results like the one below which should just be [0,0].

[8]:
binning_geometry.spatial_centre
[8]:
$[1.4325458 \times 10^{-16},~1.2111524 \times 10^{-16}] \; \mathrm{{}^{\circ}}$

GammaBinning methods

to_dict

This method will take the axes and put them in a dictionary like the one below

[9]:
binning_geometry.to_dict()
[9]:
{'energy_axis': <Quantity [  0.1       ,   0.15848932,   0.25118864,   0.39810717,
              0.63095734,   1.        ,   1.58489319,   2.51188643,
              3.98107171,   6.30957344,  10.        ,  15.84893192,
             25.11886432,  39.81071706,  63.09573445, 100.        ] TeV>,
 'lon_axis': <Quantity [-3. , -2.8, -2.6, -2.4, -2.2, -2. , -1.8, -1.6, -1.4, -1.2,
            -1. , -0.8, -0.6, -0.4, -0.2,  0. ,  0.2,  0.4,  0.6,  0.8,
             1. ,  1.2,  1.4,  1.6,  1.8,  2. ,  2.2,  2.4,  2.6,  2.8,
             3. ] deg>,
 'lat_axis': <Quantity [-2. , -1.6, -1.2, -0.8, -0.4,  0. ,  0.4,  0.8,  1.2,  1.6,
             2. ] deg>}

from_params

This method allow you to construct a GammaBinning object by giving the axis information like minima, maxima and bin size. It is useful for high level setups where you can have a dictionary of the float values within a yaml file for example and pass them into this method.

[10]:
axis_info = {
    'lon_min': -2,
    'lon_max': 2,
    'lon_bin_size': 0.2,
    'lat_min': -1,
    'lat_max': 1,
    'lat_bin_size': 0.4,
    'energy_min': 0.2,
    'energy_max': 80,
    'energy_bins_per_decade': 10,
    'energy_unit': "TeV",
    'angle_unit': "deg",
}




new_binning_geometry = GammaBinning.from_params(**axis_info)

new_binning_geometry.axes, new_binning_geometry.axes_dim
[10]:
([<Quantity [ 0.2       ,  0.25183102,  0.31709432,  0.39927093,  0.50274402,
              0.6330327 ,  0.79708636,  1.00365536,  1.26375777,  1.59126705,
              2.00365203,  2.52290868,  3.17673334,  4.        ,  5.03662042,
              6.34188631,  7.98541852, 10.05488049, 12.6606541 , 15.94172723,
             20.07310722, 25.27515542, 31.82534097, 40.07304053, 50.45817354,
             63.53466679, 80.        ] TeV>,
  <Quantity [-2.0000000e+00, -1.8000000e+00, -1.6000000e+00, -1.4000000e+00,
             -1.2000000e+00, -1.0000000e+00, -8.0000000e-01, -6.0000000e-01,
             -4.0000000e-01, -2.0000000e-01, -4.4408921e-16,  2.0000000e-01,
              4.0000000e-01,  6.0000000e-01,  8.0000000e-01,  1.0000000e+00,
              1.2000000e+00,  1.4000000e+00,  1.6000000e+00,  1.8000000e+00,
              2.0000000e+00] deg>,
  <Quantity [-1. , -0.6, -0.2,  0.2,  0.6,  1. ] deg>],
 (27, 21, 6))

GammaBinning behaviours

Equality

You can also check to see if two GammaBinning instances are equal, or not equal.

[11]:
new_binning_geometry==binning_geometry, new_binning_geometry!=binning_geometry
[11]:
(False, True)

Containment

You can also check if one instance of a binning geometry is entirely contained within another.

This will return True the bounds for one are equal to or more constrained than the other, and False if any axis sits out the other.

If we use the two bin geometries defined above, the new_binning_geometry has energy and angular axes contained within the bounds of binning_geometry, so we get the following.

[12]:
new_binning_geometry<binning_geometry, new_binning_geometry<=binning_geometry, new_binning_geometry>binning_geometry, new_binning_geometry>=binning_geometry
[12]:
(True, True, False, False)

Now let’s say we make a third binning_geometry that has the same bounds as binning_geometry but different resolutions. Then the comparison statements would say that they are equal.

[18]:
energy_axis     = np.logspace(-1,2, 31)*u.TeV
longitude_axis  = np.linspace(-3, 3, 61)*u.deg
latitude_axis   = np.linspace(-2, 2, 21)*u.deg


new_new_binning_geometry = GammaBinning(energy_axis=energy_axis, lon_axis=longitude_axis, lat_axis=latitude_axis)
[19]:
new_new_binning_geometry<binning_geometry, new_new_binning_geometry<=binning_geometry, new_new_binning_geometry>binning_geometry, new_new_binning_geometry>=binning_geometry
[19]:
(False, True, False, True)

But they are not the same so an equality comparison will return False.

[20]:
new_new_binning_geometry==binning_geometry
[20]:
False

Next tutorial

The next recommend tutorial is dealing with exposures within GammaBayes.