uvex_transients.simulation.core.SurveySimulator.compute_effective_exposure#

SurveySimulator.compute_effective_exposure(time_bins: Time | int, nside: int | None = None, order: str | None = None) → ExposureCatalog[source]#

Tabulate each registered transient type’s effective exposure per time bin.

For each transient type and each bin [t_k, t_{k+1}) of time_bins, this reruns exactly the footprint query generate_events uses to decide where it’s even worth sampling events – the HEALPix pixels the survey observes at some point between t_k and t_k+1 + transient.duration_limit – but instead of drawing a population from it, reduces it straight to a solid angle \(F(t_k, t_{k+1}+\tau)\). The effective exposure for that bin is then

\[\mathcal E_k = F(t_k, t_{k+1}+\tau)\,(t_{k+1}-t_k),\]

i.e. the visited solid angle (not the full \(4\pi\) sky) times the bin width (not the padded window used only to decide which pixels are visitable). This matches the solid_angle * duration product ~uvex_transients.transients.base.ExtragalacticTransient.sample_event_count itself feeds to numpy.random.Generator.poisson inside ~uvex_transients.transients.base.ExtragalacticTransient.sample_events_on_healpix_grid, so effective_exposure * transient.integrated_rate reproduces the same per-bin expected event count generate_events actually samples from – summing expected_events over every bin for one transient type gives the same expectation as transient.compute_all_sky_yield only when the survey footprint never misses any of the sky at any point (\(F\equiv4\pi\,\mathrm{sr}\)); otherwise this is the tighter, footprint-aware quantity that estimator ignores.

This is deliberately not extracted from a generate_events call after the fact – generate_events never persists per-bin pixel IDs or solid angles once it’s done sampling from them, and re-deriving those from a resulting ~uvex_transients.simulation.event_catalog.EventCatalog would have to guess at the very footprint query that produced it. Calling this separately recomputes that query, but the expensive part – SurveySchedule.get_healpix_coverage_index’s whole-schedule rasterization – is cached per (nside, order) and so is paid for at most once, however many times either method (or both) queries it.

Parameters:
  • time_bins (Time or int) – Same semantics as generate_events.

  • nside (int, optional) – Same semantics as generate_events.

  • order (str, optional) – Same semantics as generate_events.

Returns:

One row per (transient type, time bin), sorted by transient type then bin index, with columns transient_type, time_bin, t_start, t_end, n_pixels_visited, solid_angle, duration, effective_exposure, and expected_events. See ExposureCatalog.total_effective_exposure/ExposureCatalog.total_expected_events for the per-type sums over every bin.

Return type:

ExposureCatalog

Raises:

ValueError – If no transient types are registered in transient_collection.