Skip to content

detectability - Detectability Analysis API

Main class for analyzing and visualizing detectability data from lookup tables.

class LookupData(
input_file: str | Path,
delay_column: str = "obs_delay",
obs_time_column: str = "obs_time",
)
ParameterTypeDescription
input_filestr | PathPath to lookup table file (Parquet or CSV)
delay_columnstrName of delay column (default: "obs_delay")
obs_time_columnstrName of observation time column (default: "obs_time")
AttributeTypeDescription
dfpd.DataFrameCurrent (filtered) data frame
observation_timesnp.ndarrayObservation times used for calculations
resultspd.DataFrameCalculated detectability results with columns: delay, obs_time, n_seen, total, percent_seen

Set filters on the current data frame. Filters are applied sequentially, and each filter must match for a row to be included.

Parameters:

  • *args: Filter tuples, each of the form (column, operator, value)
    • Operators: ==, =, <, >, <=, >=, in, not in, notin
    • Values can be single values or lists (for ‘in’ operations)

Raises:

  • TypeError: If a filter is not a tuple
  • ValueError: If operator is invalid or column doesn’t exist

Example:

data.set_filters(
("irf_site", "==", "north"),
("irf_zenith", "<", 40),
("event_id", "in", [1, 2, 3]),
)

set_observation_times(obs_times: np.ndarray | list[int]) -> None

Section titled “set_observation_times(obs_times: np.ndarray | list[int]) -> None”

Set the observation times for calculations.

Parameters:

  • obs_times: Array or list of observation times in seconds

Reset the current data frame to the full data set and clear results.

Generate a heatmap of detectability data.

Parameters:

ParameterTypeDefaultDescription
axplt.Axes | NoneNoneMatplotlib axes to plot on
output_filestr | Path | NoneNonePath to save the plot
annotateboolFalseWhether to annotate cells with values
x_tick_labelsnp.ndarray | list[str] | NoneNoneCustom labels for x-axis ticks
y_tick_labelsnp.ndarray | list[str] | NoneNoneCustom labels for y-axis ticks
min_valuefloat | NoneNoneMinimum value for color scale
max_valuefloat | NoneNoneMaximum value for color scale
color_schemestr"mako"Colormap name
color_scalestr | NoneNoneColor scale type ("log" for logarithmic)
as_percentboolFalseIf True, display values as percentages (0-100)
titlestr | NoneNoneCustom title string
title_callbackCallable[[pd.DataFrame, pd.DataFrame], str] | NoneNoneCallable that receives (data, results) and returns title string
n_labelsint10Number of tick labels to display on axes
squareboolTrueIf True, make cells square-shaped
return_axboolTrueIf True, return axes object; if False, show plot
tick_fontsizeint12Font size for tick labels
label_fontsizeint16Font size for axis labels
max_exposurefloat | NoneNoneMaximum exposure time in hours. If provided, overrides default obs_times

Returns: Matplotlib axes object if return_ax=True, otherwise None

Example:

ax = data.plot(
title="My Detectability Plot",
max_exposure=2,
as_percent=True,
color_scheme="viridis",
)
from sensipy.detectability import LookupData
from sensipy.data.create_mock_lookup import create_mock_lookup_table
# Create and load data
lookup_path = create_mock_lookup_table(n_events=5)
data = LookupData(lookup_path)
# Apply filters
data.set_filters(("irf_site", "==", "north"), ("irf_zenith", "==", 20))
# Set observation times
data.set_observation_times([10, 100, 1000, 10000])
# Create plot
ax = data.plot(title="North Site, z20", max_exposure=1)

Create a grid of detectability heatmaps for comparing multiple configurations.

def create_heatmap_grid(
lookup_data_list: list[LookupData],
grid_size: tuple[int, int],
max_exposure: float | int | None = None,
max_value: float | None = None,
title: str | None = None,
subtitles: list[str] | None = None,
n_labels: int = 10,
tick_fontsize: int = 12,
label_fontsize: int = 16,
square: bool = False,
cmap: str = "mako",
**plot_kwargs,
) -> tuple[plt.Figure, np.ndarray]
ParameterTypeDescription
lookup_data_listlist[LookupData]List of LookupData instances to plot
grid_sizetuple[int, int]Tuple (rows, cols) specifying grid dimensions
max_exposurefloat | int | NoneMaximum exposure time in hours. If None, uses default obs_times.
max_valuefloat | NoneMaximum value for color scale. If None, auto-determined
titlestr | NoneOverall title for the grid
subtitleslist[str] | NoneList of titles for each subplot
n_labelsintNumber of tick labels on axes
tick_fontsizeintFont size for tick labels
label_fontsizeintFont size for axis labels
squareboolWhether to make cells square-shaped
cmapstrColormap name
**plot_kwargsAdditional keyword arguments passed to plot() method

Tuple of (figure, axes array).

from sensipy.detectability import LookupData, create_heatmap_grid
# Create multiple LookupData objects
data1 = LookupData(lookup_path)
data1.set_filters(("irf_site", "==", "north"), ("irf_zenith", "==", 20))
data2 = LookupData(lookup_path)
data2.set_filters(("irf_site", "==", "north"), ("irf_zenith", "==", 40))
# Create grid
fig, axes = create_heatmap_grid(
[data1, data2],
grid_size=(1, 2),
max_exposure=1,
title="Comparison",
subtitles=["North z20", "North z40"],
)

Convert a time in seconds to a human-readable string representation.

def convert_time(seconds: float) -> str
ParameterTypeDescription
secondsfloatTime in seconds

String representation (e.g., "30s", "2m", "1h", "1d").

from sensipy.detectability import convert_time
print(convert_time(30)) # "30s"
print(convert_time(3600)) # "1h"
print(convert_time(86400)) # "1d"