diff --git a/_modules/pyirf/irf/effective_area.html b/_modules/pyirf/irf/effective_area.html index 3348e5d9..0b5b1512 100644 --- a/_modules/pyirf/irf/effective_area.html +++ b/_modules/pyirf/irf/effective_area.html @@ -103,6 +103,8 @@

Source code for pyirf.irf.effective_area

     "effective_area",
     "effective_area_per_energy",
     "effective_area_per_energy_and_fov",
+    "effective_area_3d_polar",
+    "effective_area_3d_lonlat",
 ]
 
 
@@ -190,6 +192,113 @@ 

Source code for pyirf.irf.effective_area

 
     return effective_area(hist_selected, hist_simulated, area)
+ + +
+[docs] +def effective_area_3d_polar( + selected_events, + simulation_info, + true_energy_bins, + fov_offset_bins, + fov_position_angle_bins, +): + """ + Calculate effective area in bins of true energy, field of view offset, and field of view position angle. + + Parameters + ---------- + selected_events: astropy.table.QTable + DL2 events table, required columns for this function: + - `true_energy` + - `true_source_fov_offset` + - `true_source_fov_position_angle` + simulation_info: pyirf.simulations.SimulatedEventsInfo + The overall statistics of the simulated events + true_energy_bins: astropy.units.Quantity[energy] + The true energy bin edges in which to calculate effective area. + fov_offset_bins: astropy.units.Quantity[angle] + The field of view radial bin edges in which to calculate effective area. + fov_position_angle_bins: astropy.units.Quantity[radian] + The field of view azimuthal bin edges in which to calculate effective area. + """ + area = np.pi * simulation_info.max_impact**2 + + hist_simulated = simulation_info.calculate_n_showers_3d_polar( + true_energy_bins, fov_offset_bins, fov_position_angle_bins + ) + + hist_selected, _ = np.histogramdd( + np.column_stack( + [ + selected_events["true_energy"].to_value(u.TeV), + selected_events["true_source_fov_offset"].to_value(u.deg), + selected_events["true_source_fov_position_angle"].to_value(u.rad), + ] + ), + bins=( + true_energy_bins.to_value(u.TeV), + fov_offset_bins.to_value(u.deg), + fov_position_angle_bins.to_value(u.rad), + ), + ) + + return effective_area(hist_selected, hist_simulated, area)
+ + + +
+[docs] +def effective_area_3d_lonlat( + selected_events, + simulation_info, + true_energy_bins, + fov_longitude_bins, + fov_latitude_bins, + subpixels=20, +): + """ + Calculate effective area in bins of true energy, field of view longitude, and field of view latitude. + + Parameters + ---------- + selected_events: astropy.table.QTable + DL2 events table, required columns for this function: + - `true_energy` + - `true_source_fov_lon` + - `true_source_fov_lat` + simulation_info: pyirf.simulations.SimulatedEventsInfo + The overall statistics of the simulated events + true_energy_bins: astropy.units.Quantity[energy] + The true energy bin edges in which to calculate effective area. + fov_longitude_bins: astropy.units.Quantity[angle] + The field of view longitude bin edges in which to calculate effective area. + fov_latitude_bins: astropy.units.Quantity[angle] + The field of view latitude bin edges in which to calculate effective area. + """ + area = np.pi * simulation_info.max_impact**2 + + hist_simulated = simulation_info.calculate_n_showers_3d_lonlat( + true_energy_bins, fov_longitude_bins, fov_latitude_bins, subpixels=subpixels + ) + + selected_columns = np.column_stack( + [ + selected_events["true_energy"].to_value(u.TeV), + selected_events["true_source_fov_lon"].to_value(u.deg), + selected_events["true_source_fov_lat"].to_value(u.deg), + ] + ) + bins = ( + true_energy_bins.to_value(u.TeV), + fov_longitude_bins.to_value(u.deg), + fov_latitude_bins.to_value(u.deg), + ) + + hist_selected, _ = np.histogramdd(selected_columns, bins=bins) + + return effective_area(hist_selected, hist_simulated, area)
+
diff --git a/_modules/pyirf/simulations.html b/_modules/pyirf/simulations.html index d6346bdd..43d1086c 100644 --- a/_modules/pyirf/simulations.html +++ b/_modules/pyirf/simulations.html @@ -96,6 +96,10 @@

Source code for pyirf.simulations

 import astropy.units as u
 import numpy as np
+from astropy.coordinates import angular_separation
+from .utils import cone_solid_angle
+from .utils import rectangle_solid_angle
+from .binning import bin_center
 
 __all__ = [
     'SimulatedEventsInfo',
@@ -275,6 +279,113 @@ 

Source code for pyirf.simulations

         return e_integral[:, np.newaxis] * fov_integral / self.n_showers
+
+[docs] + @u.quantity_input( + energy_bins=u.TeV, fov_offset_bins=u.deg, fov_position_angle_bins=u.rad + ) + def calculate_n_showers_3d_polar( + self, energy_bins, fov_offset_bins, fov_position_angle_bins + ): + """ + Calculate number of showers that were simulated in the given + energy and 2D fov bins in polar coordinates. + + This assumes the events were generated uniformly distributed per solid angle, + and from a powerlaw in energy like CORSIKA simulates events. + + Parameters + ---------- + energy_bins: astropy.units.Quantity[energy] + The energy bin edges for which to calculate the number of simulated showers + fov_offset_bins: astropy.units.Quantity[angle] + The FOV radial bin edges for which to calculate the number of simulated showers + fov_position_angle_bins: astropy.units.Quantity[radian] + The FOV azimuthal bin edges for which to calculate the number of simulated showers + + Returns + ------- + n_showers: numpy.ndarray(ndim=3) + The expected number of events inside each of the + ``energy_bins``, ``fov_offset_bins`` and ``fov_position_angle_bins``. + Dimension (n_energy_bins, n_fov_offset_bins, n_fov_position_angle_bins) + This is a floating point number. + The actual numbers will follow a poissionian distribution around this + expected value. + """ + e_fov_offset_integral = self.calculate_n_showers_per_energy_and_fov( + energy_bins, fov_offset_bins + ) + viewcone_integral = self.calculate_n_showers_per_fov( + [self.viewcone_min, self.viewcone_max] * u.deg + ) + + n_bins_pa = len(fov_position_angle_bins) - 1 + position_angle_integral = np.full(n_bins_pa, viewcone_integral / n_bins_pa) + + total_integral = e_fov_offset_integral[:, :, np.newaxis] * position_angle_integral + + return total_integral / self.n_showers
+ + +
+[docs] + @u.quantity_input( + energy_bins=u.TeV, fov_longitude_bins=u.deg, fov_latitude_bins=u.rad + ) + def calculate_n_showers_3d_lonlat( + self, energy_bins, fov_longitude_bins, fov_latitude_bins, subpixels=20 + ): + """ + Calculate number of showers that were simulated in the given + energy and 2D fov bins in nominal coordinates. + + This assumes the events were generated uniformly distributed per solid angle, + and from a powerlaw in energy like CORSIKA simulates events. + + Parameters + ---------- + energy_bins: astropy.units.Quantity[energy] + The energy bin edges for which to calculate the number of simulated showers + fov_longitude_bins: astropy.units.Quantity[angle] + The FOV longitude bin edges for which to calculate the number of simulated showers + fov_latitude_bins: astropy.units.Quantity[angle] + The FOV latitude bin edges for which to calculate the number of simulated showers + + Returns + ------- + n_showers: numpy.ndarray(ndim=3) + The expected number of events inside each of the + ``energy_bins``, ``fov_longitude_bins`` and ``fov_latitude_bins``. + Dimension (n_energy_bins, n_fov_longitude_bins, n_fov_latitude_bins) + This is a floating point number. + The actual numbers will follow a poissionian distribution around this + expected value. + """ + + fov_overlap = _fov_lonlat_grid_overlap( + self, fov_longitude_bins, fov_latitude_bins, subpixels=subpixels + ) + + bin_grid_lon, bin_grid_lat = np.meshgrid(fov_longitude_bins,fov_latitude_bins) + bin_area = rectangle_solid_angle( + bin_grid_lon[:-1,:-1], + bin_grid_lon[1:,1:], + bin_grid_lat[:-1,:-1], + bin_grid_lat[1:,1:], + ) + viewcone_area = cone_solid_angle(self.viewcone_max) - cone_solid_angle(self.viewcone_min) + + shower_density = self.n_showers / viewcone_area + + fov_integral = shower_density * bin_area + e_integral = self.calculate_n_showers_per_energy(energy_bins) + + fov_integral = fov_overlap * fov_integral + + return (e_integral[:, np.newaxis, np.newaxis] * fov_integral) / self.n_showers
+ + def __repr__(self): return ( f"{self.__class__.__name__}(" @@ -332,6 +443,119 @@

Source code for pyirf.simulations

     if scalar:
         return np.squeeze(integral)
     return integral
+
+def _fov_lonlat_grid_overlap(self, bin_edges_lon, bin_edges_lat, subpixels=20):
+    """
+    When binning in longitude and latitude there might be bins that are fully or
+    partially outside of the simulated viewcone window.
+
+    Subdivides each bin on the edge of the viewcone and calculates the fraction of
+    'subpixels' whose centers are inside the viewcone, which approximates the area of the
+    bin inside the viewcone.
+    """
+    # treat edge cases where all bins are either fully inside or outside of the viewcone
+    bin_grid_lon, bin_grid_lat = np.meshgrid(bin_edges_lon, bin_edges_lat)
+
+    bin_dist = angular_separation(
+        bin_grid_lon,
+        bin_grid_lat,
+        0,
+        0,
+    ).to_value(u.deg)
+
+    all_outside = np.logical_or(
+        np.all(bin_dist <= self.viewcone_min.to_value(u.deg)),
+        np.all(bin_dist >= self.viewcone_max.to_value(u.deg)),
+    )
+    all_inside = np.logical_and(
+        np.all(bin_dist <= self.viewcone_max.to_value(u.deg)),
+        np.all(bin_dist >= self.viewcone_min.to_value(u.deg)),
+    )
+
+    if all_outside:
+        return 0
+    elif all_inside:
+        return 1
+
+
+    # define grid of bin centers
+    fov_bin_centers_lon = bin_center(bin_edges_lon)
+    fov_bin_centers_lat = bin_center(bin_edges_lat)
+
+    bin_centers_grid_lon, bin_centers_grid_lat = np.meshgrid(
+        fov_bin_centers_lon, fov_bin_centers_lat,
+    )
+
+    # calculate angular separation of bin centers to FOV center
+    radius_bin_center = angular_separation(
+        bin_centers_grid_lon,
+        bin_centers_grid_lat,
+        0,
+        0,
+    )
+
+    # simple area mask with all bin centers outside FOV = 0
+    mask_simple = np.logical_or(
+        radius_bin_center > self.viewcone_max,
+        radius_bin_center < self.viewcone_min,
+    )
+
+    area = np.ones(mask_simple.shape)
+    area[mask_simple] = 0
+
+    # select only bins partially covered by the FOV
+    bin_width_lon = bin_edges_lon[1] - bin_edges_lon[0]
+    bin_width_lat = bin_edges_lat[1] - bin_edges_lat[0]
+    bin_max_radius = np.sqrt(bin_width_lon ** 2 + bin_width_lat ** 2) * 0.5
+
+    fov_outer_edge_mask = np.logical_and(
+        radius_bin_center < self.viewcone_max + bin_max_radius,
+        radius_bin_center > self.viewcone_max - bin_max_radius,
+    )
+    fov_inner_edge_mask = np.logical_and(
+        radius_bin_center < self.viewcone_min + bin_max_radius,
+        radius_bin_center > self.viewcone_min - bin_max_radius,
+    )
+
+    fov_edge_mask = np.logical_or(fov_inner_edge_mask, fov_outer_edge_mask)
+
+    # get indices of relevant bin corners
+    corner_idx = np.nonzero(fov_edge_mask)
+
+    # define start and endpoints for subpixels
+    edges_lon = np.array(
+        [bin_grid_lon[corner_idx], bin_grid_lon[corner_idx] + bin_width_lon]
+    )
+    edges_lat = np.array(
+        [bin_grid_lat[corner_idx], bin_grid_lat[corner_idx] + bin_width_lat]
+    )
+
+    n_edge_pixels = len(fov_edge_mask[fov_edge_mask==True])
+
+    # define subpixel bin centers and grid
+    subpixel_lon = bin_center(np.linspace(*edges_lon, subpixels + 1) * u.deg)
+    subpixel_lat = bin_center(np.linspace(*edges_lat, subpixels + 1) * u.deg)
+
+    # shape: (n_edge_pixels, 2, subpixels, subpixels)
+    subpixel_grid = np.array(
+        [np.meshgrid(subpixel_lon[:,i], subpixel_lat[:,i]) for i in range(n_edge_pixels)]
+    )
+    subpixel_grid_lon = subpixel_grid[:,0] * u.deg
+    subpixel_grid_lat = subpixel_grid[:,1] * u.deg
+
+    # make mask with subpixels inside the FOV
+    radius_subpixel = angular_separation(subpixel_grid_lon, subpixel_grid_lat, 0, 0)
+    mask = np.logical_and(
+        radius_subpixel <= self.viewcone_max,
+        radius_subpixel >= self.viewcone_min,
+    )
+
+    # calculates the fraction of subpixel centers within the FOV
+    FOV_covered_area = mask.sum(axis=(1,2)) / (subpixels ** 2)
+
+    area[corner_idx] = FOV_covered_area
+
+    return area
 
diff --git a/_modules/pyirf/utils.html b/_modules/pyirf/utils.html index ea46192b..6815af5d 100644 --- a/_modules/pyirf/utils.html +++ b/_modules/pyirf/utils.html @@ -97,6 +97,7 @@

Source code for pyirf.utils

 import numpy as np
 import astropy.units as u
 from astropy.coordinates import angular_separation
+from .coordinates import gadf_fov_coords_theta_phi, gadf_fov_coords_lon_lat
 
 from .compat import COPY_IF_NEEDED
 from .exceptions import MissingColumns, WrongColumnUnit
@@ -106,6 +107,7 @@ 

Source code for pyirf.utils

     "is_scalar",
     "calculate_theta",
     "calculate_source_fov_offset",
+    "calculate_source_fov_position_angle",
     "check_histograms",
     "cone_solid_angle",
 ]
@@ -194,6 +196,65 @@ 

Source code for pyirf.utils

 
 
 
+
+[docs] +def calculate_source_fov_position_angle(events, prefix="true"): + """Calculate position_angle of true positions relative to pointing positions. + + Parameters + ---------- + events : astropy.QTable + Astropy Table object containing the reconstructed events information. + + prefix: str + Column prefix for az / alt, can be used to calculate reco or true + source fov position_angle. + + Returns + ------- + phi: astropy.units.Quantity + Position angle of the true positions relative to the pointing positions + in the sky. + """ + _, phi = gadf_fov_coords_theta_phi( + events[f"{prefix}_az"], + events[f"{prefix}_alt"], + events["pointing_az"], + events["pointing_alt"], + ) + + return phi.to(u.deg)
+ + + +def calculate_source_fov_lonlat(events, prefix="true"): + """Calculate position_angle of true positions relative to pointing positions. + + Parameters + ---------- + events : astropy.QTable + Astropy Table object containing the reconstructed events information. + + prefix: str + Column prefix for az / alt, can be used to calculate reco or true + source fov position_angle. + + Returns + ------- + phi: astropy.units.Quantity + Position angle of the true positions relative to the pointing positions + in the sky. + """ + lon, lat = gadf_fov_coords_lon_lat( + events[f"{prefix}_az"], + events[f"{prefix}_alt"], + events["pointing_az"], + events["pointing_alt"], + ) + + return lon.to(u.deg), lat.to(u.deg) + +
[docs] def check_histograms(hist1, hist2, key="reco_energy"): @@ -240,6 +301,32 @@

Source code for pyirf.utils

 
 
 
+def rectangle_solid_angle(lon_low, lon_high, lat_low, lat_high):
+    """Calculate the solid angle of a latitude-longitude rectangle
+
+    Parameters
+    ----------
+    lon_low: astropy.units.Quantity[angle]
+        Lower longitude coordinate of the rectangle corner
+    lat_low: astropy.units.Quantity[angle]
+        Lower latitude coordinate of the rectangle corner
+    lon_high: astropy.units.Quantity[angle]
+        Higher longitude coordinate of the rectangle corner
+    lat_high: astropy.units.Quantity[angle]
+        Higher Latitude coordinates of the rectangle corner
+
+    Returns
+    -------
+    solid angle: astropy.units.Quantity[solid angle]
+
+    """
+    diff_lon = (lon_high - lon_low).to_value(u.rad)
+    diff_lat = np.sin(lat_high.to_value(u.rad)) - np.sin(lat_low.to_value(u.rad))
+
+    solid_angle = diff_lon * diff_lat * u.sr
+    return solid_angle
+
+
 def check_table(table, required_columns=None, required_units=None):
     """Check a table for required columns and units.
 
diff --git a/_sources/api/pyirf.irf.effective_area_3d_lonlat.rst.txt b/_sources/api/pyirf.irf.effective_area_3d_lonlat.rst.txt
new file mode 100644
index 00000000..e7fab68b
--- /dev/null
+++ b/_sources/api/pyirf.irf.effective_area_3d_lonlat.rst.txt
@@ -0,0 +1,6 @@
+effective_area_3d_lonlat
+========================
+
+.. currentmodule:: pyirf.irf
+
+.. autofunction:: effective_area_3d_lonlat
diff --git a/_sources/api/pyirf.irf.effective_area_3d_polar.rst.txt b/_sources/api/pyirf.irf.effective_area_3d_polar.rst.txt
new file mode 100644
index 00000000..e27625e0
--- /dev/null
+++ b/_sources/api/pyirf.irf.effective_area_3d_polar.rst.txt
@@ -0,0 +1,6 @@
+effective_area_3d_polar
+=======================
+
+.. currentmodule:: pyirf.irf
+
+.. autofunction:: effective_area_3d_polar
diff --git a/_sources/api/pyirf.simulations.SimulatedEventsInfo.rst.txt b/_sources/api/pyirf.simulations.SimulatedEventsInfo.rst.txt
index b702fbc3..37b266d9 100644
--- a/_sources/api/pyirf.simulations.SimulatedEventsInfo.rst.txt
+++ b/_sources/api/pyirf.simulations.SimulatedEventsInfo.rst.txt
@@ -22,6 +22,8 @@ SimulatedEventsInfo
 
    .. autosummary::
 
+      ~SimulatedEventsInfo.calculate_n_showers_3d_lonlat
+      ~SimulatedEventsInfo.calculate_n_showers_3d_polar
       ~SimulatedEventsInfo.calculate_n_showers_per_energy
       ~SimulatedEventsInfo.calculate_n_showers_per_energy_and_fov
       ~SimulatedEventsInfo.calculate_n_showers_per_fov
@@ -38,6 +40,8 @@ SimulatedEventsInfo
 
    .. rubric:: Methods Documentation
 
+   .. automethod:: calculate_n_showers_3d_lonlat
+   .. automethod:: calculate_n_showers_3d_polar
    .. automethod:: calculate_n_showers_per_energy
    .. automethod:: calculate_n_showers_per_energy_and_fov
    .. automethod:: calculate_n_showers_per_fov
diff --git a/_sources/api/pyirf.utils.calculate_source_fov_position_angle.rst.txt b/_sources/api/pyirf.utils.calculate_source_fov_position_angle.rst.txt
new file mode 100644
index 00000000..a7902a84
--- /dev/null
+++ b/_sources/api/pyirf.utils.calculate_source_fov_position_angle.rst.txt
@@ -0,0 +1,6 @@
+calculate_source_fov_position_angle
+===================================
+
+.. currentmodule:: pyirf.utils
+
+.. autofunction:: calculate_source_fov_position_angle
diff --git a/api/pyirf.irf.background_2d.html b/api/pyirf.irf.background_2d.html
index fbc98bae..790fa904 100644
--- a/api/pyirf.irf.background_2d.html
+++ b/api/pyirf.irf.background_2d.html
@@ -68,6 +68,8 @@
 
  • effective_area
  • effective_area_per_energy
  • effective_area_per_energy_and_fov
  • +
  • effective_area_3d_polar
  • +
  • effective_area_3d_lonlat
  • energy_dispersion
  • psf_table
  • background_2d
  • diff --git a/api/pyirf.irf.effective_area.html b/api/pyirf.irf.effective_area.html index e867ed94..e4c97757 100644 --- a/api/pyirf.irf.effective_area.html +++ b/api/pyirf.irf.effective_area.html @@ -68,6 +68,8 @@
  • effective_area
  • effective_area_per_energy
  • effective_area_per_energy_and_fov
  • +
  • effective_area_3d_polar
  • +
  • effective_area_3d_lonlat
  • energy_dispersion
  • psf_table
  • background_2d
  • diff --git a/api/pyirf.irf.effective_area_3d_lonlat.html b/api/pyirf.irf.effective_area_3d_lonlat.html new file mode 100644 index 00000000..917d2db3 --- /dev/null +++ b/api/pyirf.irf.effective_area_3d_lonlat.html @@ -0,0 +1,181 @@ + + + + + + + + + effective_area_3d_lonlat — pyirf documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    effective_area_3d_lonlat

    +
    +
    +pyirf.irf.effective_area_3d_lonlat(selected_events, simulation_info, true_energy_bins, fov_longitude_bins, fov_latitude_bins, subpixels=20)[source]
    +

    Calculate effective area in bins of true energy, field of view longitude, and field of view latitude.

    +
    +
    Parameters:
    +
    +
    selected_events: astropy.table.QTable

    DL2 events table, required columns for this function: +- true_energy +- true_source_fov_lon +- true_source_fov_lat

    +
    +
    simulation_info: pyirf.simulations.SimulatedEventsInfo

    The overall statistics of the simulated events

    +
    +
    true_energy_bins: astropy.units.Quantity[energy]

    The true energy bin edges in which to calculate effective area.

    +
    +
    fov_longitude_bins: astropy.units.Quantity[angle]

    The field of view longitude bin edges in which to calculate effective area.

    +
    +
    fov_latitude_bins: astropy.units.Quantity[angle]

    The field of view latitude bin edges in which to calculate effective area.

    +
    +
    +
    +
    +
    + +
    + + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/api/pyirf.irf.effective_area_3d_polar.html b/api/pyirf.irf.effective_area_3d_polar.html new file mode 100644 index 00000000..791f7299 --- /dev/null +++ b/api/pyirf.irf.effective_area_3d_polar.html @@ -0,0 +1,181 @@ + + + + + + + + + effective_area_3d_polar — pyirf documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    effective_area_3d_polar

    +
    +
    +pyirf.irf.effective_area_3d_polar(selected_events, simulation_info, true_energy_bins, fov_offset_bins, fov_position_angle_bins)[source]
    +

    Calculate effective area in bins of true energy, field of view offset, and field of view position angle.

    +
    +
    Parameters:
    +
    +
    selected_events: astropy.table.QTable

    DL2 events table, required columns for this function: +- true_energy +- true_source_fov_offset +- true_source_fov_position_angle

    +
    +
    simulation_info: pyirf.simulations.SimulatedEventsInfo

    The overall statistics of the simulated events

    +
    +
    true_energy_bins: astropy.units.Quantity[energy]

    The true energy bin edges in which to calculate effective area.

    +
    +
    fov_offset_bins: astropy.units.Quantity[angle]

    The field of view radial bin edges in which to calculate effective area.

    +
    +
    fov_position_angle_bins: astropy.units.Quantity[radian]

    The field of view azimuthal bin edges in which to calculate effective area.

    +
    +
    +
    +
    +
    + +
    + + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/api/pyirf.irf.effective_area_per_energy.html b/api/pyirf.irf.effective_area_per_energy.html index 4213c5ca..cf66d215 100644 --- a/api/pyirf.irf.effective_area_per_energy.html +++ b/api/pyirf.irf.effective_area_per_energy.html @@ -68,6 +68,8 @@
  • effective_area
  • effective_area_per_energy
  • effective_area_per_energy_and_fov
  • +
  • effective_area_3d_polar
  • +
  • effective_area_3d_lonlat
  • energy_dispersion
  • psf_table
  • background_2d
  • diff --git a/api/pyirf.irf.effective_area_per_energy_and_fov.html b/api/pyirf.irf.effective_area_per_energy_and_fov.html index afb7fab1..342dcaf9 100644 --- a/api/pyirf.irf.effective_area_per_energy_and_fov.html +++ b/api/pyirf.irf.effective_area_per_energy_and_fov.html @@ -22,7 +22,7 @@ - + @@ -68,6 +68,8 @@
  • effective_area
  • effective_area_per_energy
  • effective_area_per_energy_and_fov
  • +
  • effective_area_3d_polar
  • +
  • effective_area_3d_lonlat
  • energy_dispersion
  • psf_table
  • background_2d
  • @@ -147,7 +149,7 @@

    effective_area_per_energy_and_fov - +


    diff --git a/api/pyirf.irf.energy_dispersion.html b/api/pyirf.irf.energy_dispersion.html index 75b3033f..e5374890 100644 --- a/api/pyirf.irf.energy_dispersion.html +++ b/api/pyirf.irf.energy_dispersion.html @@ -23,7 +23,7 @@ - + @@ -68,6 +68,8 @@
  • effective_area
  • effective_area_per_energy
  • effective_area_per_energy_and_fov
  • +
  • effective_area_3d_polar
  • +
  • effective_area_3d_lonlat
  • energy_dispersion
  • psf_table
  • background_2d
  • @@ -156,7 +158,7 @@

    energy_dispersion - +

    diff --git a/api/pyirf.irf.psf_table.html b/api/pyirf.irf.psf_table.html index 9a56d9a2..2ac08d04 100644 --- a/api/pyirf.irf.psf_table.html +++ b/api/pyirf.irf.psf_table.html @@ -68,6 +68,8 @@
  • effective_area
  • effective_area_per_energy
  • effective_area_per_energy_and_fov
  • +
  • effective_area_3d_polar
  • +
  • effective_area_3d_lonlat
  • energy_dispersion
  • psf_table
  • background_2d
  • diff --git a/api/pyirf.simulations.SimulatedEventsInfo.html b/api/pyirf.simulations.SimulatedEventsInfo.html index 6aabec82..3131d5a1 100644 --- a/api/pyirf.simulations.SimulatedEventsInfo.html +++ b/api/pyirf.simulations.SimulatedEventsInfo.html @@ -164,6 +164,12 @@

    SimulatedEventsInfoMethods Summary

    + + + + + + @@ -220,6 +226,70 @@

    SimulatedEventsInfoMethods Documentation

    +
    +
    +calculate_n_showers_3d_lonlat(energy_bins, fov_longitude_bins, fov_latitude_bins, subpixels=20)[source]
    +

    Calculate number of showers that were simulated in the given +energy and 2D fov bins in nominal coordinates.

    +

    This assumes the events were generated uniformly distributed per solid angle, +and from a powerlaw in energy like CORSIKA simulates events.

    +
    +
    Parameters:
    +
    +
    energy_bins: astropy.units.Quantity[energy]

    The energy bin edges for which to calculate the number of simulated showers

    +
    +
    fov_longitude_bins: astropy.units.Quantity[angle]

    The FOV longitude bin edges for which to calculate the number of simulated showers

    +
    +
    fov_latitude_bins: astropy.units.Quantity[angle]

    The FOV latitude bin edges for which to calculate the number of simulated showers

    +
    +
    +
    +
    Returns:
    +
    +
    n_showers: numpy.ndarray(ndim=3)

    The expected number of events inside each of the +energy_bins, fov_longitude_bins and fov_latitude_bins. +Dimension (n_energy_bins, n_fov_longitude_bins, n_fov_latitude_bins) +This is a floating point number. +The actual numbers will follow a poissionian distribution around this +expected value.

    +
    +
    +
    +
    +
    + +
    +
    +calculate_n_showers_3d_polar(energy_bins, fov_offset_bins, fov_position_angle_bins)[source]
    +

    Calculate number of showers that were simulated in the given +energy and 2D fov bins in polar coordinates.

    +

    This assumes the events were generated uniformly distributed per solid angle, +and from a powerlaw in energy like CORSIKA simulates events.

    +
    +
    Parameters:
    +
    +
    energy_bins: astropy.units.Quantity[energy]

    The energy bin edges for which to calculate the number of simulated showers

    +
    +
    fov_offset_bins: astropy.units.Quantity[angle]

    The FOV radial bin edges for which to calculate the number of simulated showers

    +
    +
    fov_position_angle_bins: astropy.units.Quantity[radian]

    The FOV azimuthal bin edges for which to calculate the number of simulated showers

    +
    +
    +
    +
    Returns:
    +
    +
    n_showers: numpy.ndarray(ndim=3)

    The expected number of events inside each of the +energy_bins, fov_offset_bins and fov_position_angle_bins. +Dimension (n_energy_bins, n_fov_offset_bins, n_fov_position_angle_bins) +This is a floating point number. +The actual numbers will follow a poissionian distribution around this +expected value.

    +
    +
    +
    +
    +
    +
    calculate_n_showers_per_energy(energy_bins)[source]
    diff --git a/api/pyirf.utils.calculate_source_fov_offset.html b/api/pyirf.utils.calculate_source_fov_offset.html index 8162f726..03e85e0e 100644 --- a/api/pyirf.utils.calculate_source_fov_offset.html +++ b/api/pyirf.utils.calculate_source_fov_offset.html @@ -22,7 +22,7 @@ - + @@ -76,6 +76,7 @@
  • is_scalar
  • calculate_theta
  • calculate_source_fov_offset
  • +
  • calculate_source_fov_position_angle
  • check_histograms
  • cone_solid_angle
  • @@ -144,7 +145,7 @@

    calculate_source_fov_offset - +
    diff --git a/api/pyirf.utils.calculate_source_fov_position_angle.html b/api/pyirf.utils.calculate_source_fov_position_angle.html new file mode 100644 index 00000000..c03bb890 --- /dev/null +++ b/api/pyirf.utils.calculate_source_fov_position_angle.html @@ -0,0 +1,174 @@ + + + + + + + + + calculate_source_fov_position_angle — pyirf documentation + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +

    calculate_source_fov_position_angle

    +
    +
    +pyirf.utils.calculate_source_fov_position_angle(events, prefix='true')[source]
    +

    Calculate position_angle of true positions relative to pointing positions.

    +
    +
    Parameters:
    +
    +
    eventsastropy.QTable

    Astropy Table object containing the reconstructed events information.

    +
    +
    prefix: str

    Column prefix for az / alt, can be used to calculate reco or true +source fov position_angle.

    +
    +
    +
    +
    Returns:
    +
    +
    phi: astropy.units.Quantity

    Position angle of the true positions relative to the pointing positions +in the sky.

    +
    +
    +
    +
    +
    + +
    + + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/api/pyirf.utils.calculate_theta.html b/api/pyirf.utils.calculate_theta.html index 20d9a5a5..e34903cf 100644 --- a/api/pyirf.utils.calculate_theta.html +++ b/api/pyirf.utils.calculate_theta.html @@ -76,6 +76,7 @@
  • is_scalar
  • calculate_theta
  • calculate_source_fov_offset
  • +
  • calculate_source_fov_position_angle
  • check_histograms
  • cone_solid_angle
  • diff --git a/api/pyirf.utils.check_histograms.html b/api/pyirf.utils.check_histograms.html index b2df4224..1b946616 100644 --- a/api/pyirf.utils.check_histograms.html +++ b/api/pyirf.utils.check_histograms.html @@ -23,7 +23,7 @@ - + @@ -76,6 +76,7 @@
  • is_scalar
  • calculate_theta
  • calculate_source_fov_offset
  • +
  • calculate_source_fov_position_angle
  • check_histograms
  • cone_solid_angle
  • @@ -136,7 +137,7 @@

    check_histograms - + diff --git a/api/pyirf.utils.cone_solid_angle.html b/api/pyirf.utils.cone_solid_angle.html index 5380461c..0686ff66 100644 --- a/api/pyirf.utils.cone_solid_angle.html +++ b/api/pyirf.utils.cone_solid_angle.html @@ -75,6 +75,7 @@
  • is_scalar
  • calculate_theta
  • calculate_source_fov_offset
  • +
  • calculate_source_fov_position_angle
  • check_histograms
  • cone_solid_angle
  • diff --git a/api/pyirf.utils.is_scalar.html b/api/pyirf.utils.is_scalar.html index f451b12a..2eab2eec 100644 --- a/api/pyirf.utils.is_scalar.html +++ b/api/pyirf.utils.is_scalar.html @@ -76,6 +76,7 @@
  • is_scalar
  • calculate_theta
  • calculate_source_fov_offset
  • +
  • calculate_source_fov_position_angle
  • check_histograms
  • cone_solid_angle
  • diff --git a/changelog.html b/changelog.html index 54298eea..2eb9325b 100644 --- a/changelog.html +++ b/changelog.html @@ -53,7 +53,7 @@
  • Example Notebooks
  • How to contribute
  • Changelog
  • calculate_n_showers_3d_lonlat(energy_bins, ...)

    Calculate number of showers that were simulated in the given energy and 2D fov bins in nominal coordinates.

    calculate_n_showers_3d_polar(energy_bins, ...)

    Calculate number of showers that were simulated in the given energy and 2D fov bins in polar coordinates.

    calculate_n_showers_per_energy(energy_bins)

    Calculate number of showers that were simulated in the given energy intervals