.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/simulating/plot_tde_end_to_end.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_simulating_plot_tde_end_to_end.py: TDE End-to-End Simulation =========================== A minimal example of an end-to-end simulation of transient yields from a UVEX survey schedule. In this example, we'll determine the anticipated yield of TDEs with the default UVEX schedule. To do this, we'll take the following steps: 1. **Configure our transient class**, including changing any relevant priors, durations, etc. 2. **Draw events from the schedule**, and then 3. **Filter events by observability**. 4. **Generate synthetic photometry**. .. GENERATED FROM PYTHON SOURCE LINES 16-26 Load the schedule and set up the population ----------------------------------------------- We can start by loading the default schedule using :func:`~uvex_transients.surveys.utils.get_schedule`. We'll also want to get the TDE class configured and load the simulator. .. note:: At this stage, you can make modifications to priors as needed. .. GENERATED FROM PYTHON SOURCE LINES 26-51 .. code-block:: Python import numpy as np from astropy import units as u from m4opt.missions import uvex from matplotlib import pyplot as plt from uvex_transients.simulation.core import SurveySimulator from uvex_transients.surveys import get_schedule from uvex_transients.transients.TDEs import TidalDisruptionEvent from uvex_transients.utils.plotting import ( add_funnel_legend, compute_funnel_bounds, get_band_color, plot_band_light_curve, plot_detection_funnel, resolve_fig_axes, set_plot_style, ) set_plot_style() schedule = get_schedule() tde = TidalDisruptionEvent() simulator = SurveySimulator(schedule, transients={"tde": tde}, simulation_seed=42) .. GENERATED FROM PYTHON SOURCE LINES 52-64 Sample a Monte Carlo population ----------------------------------- We now want to draw synthetic events for the schedule. This uses a **windowed sampling** technique so that only events which fall within the instrument's footprint at some point during their duration are sampled. .. note:: For events with very high intrinsic rates, it can be useful to provide a ``downsample`` value to reduce the number of simulated events. This can then be used to rescale to the total number of events at a later point in the analysis. .. GENERATED FROM PYTHON SOURCE LINES 64-71 .. code-block:: Python TIME_BINS = 20 NSIDE = 64 DOWNSAMPLE = 20 catalog = simulator.generate_events(time_bins=TIME_BINS, nside=NSIDE, downsample=DOWNSAMPLE) print(f"Sampled {len(catalog) * DOWNSAMPLE} TDEs across {TIME_BINS} time bin(s) at NSIDE={NSIDE}.") .. rst-class:: sphx-glr-script-out .. code-block:: none Generating events: 0%| | 0/20 [00:00 {SNR_THRESHOLD}"] raw_counts = [len(catalog), len(mag_filtered), len(detected)] counts = [c * DOWNSAMPLE for c in raw_counts] mc_lower, mc_upper, rate_lower, rate_upper = compute_funnel_bounds(raw_counts, rate_ci=tde.RATE_CI) fig, ax = resolve_fig_axes() plot_detection_funnel( ax, x=np.arange(len(stages)), counts=np.asarray(counts, dtype=float), mc_lower=mc_lower * DOWNSAMPLE, mc_upper=mc_upper * DOWNSAMPLE, rate_lower=rate_lower * DOWNSAMPLE, rate_upper=rate_upper * DOWNSAMPLE, ) ax.set_xticks(np.arange(len(stages)), stages) ax.set_yscale("log") for i, count in enumerate(counts): ax.text(i, rate_upper[i] * DOWNSAMPLE, f"{count:,}", ha="center", va="bottom") ax.set_ylabel("Number of TDEs") ax.set_title("TDE detection funnel") add_funnel_legend(ax) fig.tight_layout() .. image-sg:: /auto_examples/simulating/images/sphx_glr_plot_tde_end_to_end_001.png :alt: TDE detection funnel :srcset: /auto_examples/simulating/images/sphx_glr_plot_tde_end_to_end_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 128-133 Black error bars are the MC (statistical) uncertainty on each stage's count, from treating it as a binomial subsample of the raw simulated draws (Clopper-Pearson); the pale shaded band is the rate (systematic) uncertainty from the TDE rate's own literature normalization (:attr:`~uvex_transients.transients.base.ExtragalacticTransient.RATE_CI`), which scales every stage by the same factor rather than shrinking as the sample is cut down. .. GENERATED FROM PYTHON SOURCE LINES 135-140 Sky distribution --------------------- The sampled population traces the schedule's own footprint; the detected subset is whatever fraction of it UVEX actually caught above :math:`\mathrm{SNR}=5`. .. GENERATED FROM PYTHON SOURCE LINES 140-163 .. code-block:: Python # sphinx_gallery_thumbnail_number = 2 fig, ax = resolve_fig_axes(fig_size=(8, 4), subplot_kw={"projection": "aitoff"}) ax.grid(True) ra_sampled = catalog.coord.ra.wrap_at(180 * u.deg).radian ra_detected = detected.coord.ra.wrap_at(180 * u.deg).radian ax.scatter( ra_sampled, catalog.coord.dec.radian, s=2, alpha=0.2, color="#888888", label=f"Sampled ({DOWNSAMPLE * len(catalog)})", ) ax.scatter( ra_detected, detected.coord.dec.radian, s=4, color="#55A868", label=f"Detected ({DOWNSAMPLE * (len(detected))})" ) ax.legend(loc="lower right", markerscale=4) ax.set_title("TDE sky distribution") fig.tight_layout() .. image-sg:: /auto_examples/simulating/images/sphx_glr_plot_tde_end_to_end_002.png :alt: TDE sky distribution :srcset: /auto_examples/simulating/images/sphx_glr_plot_tde_end_to_end_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 164-171 An example light curve --------------------------- Reconstruct one detected event as a real :class:`~uvex_transients.simulation.event.Event` (:meth:`~uvex_transients.simulation.event_catalog.EventCatalog.get_events`) and run full synthetic photometry (:meth:`~uvex_transients.simulation.event.Event.simulate_photometry`) against every observation the schedule actually made of it. .. GENERATED FROM PYTHON SOURCE LINES 171-203 .. code-block:: Python rng = np.random.default_rng(1) example_id = rng.choice(detected.event_id) event = detected.get_events(int(example_id), {"tde": tde}, schedule) print(event) phot = event.simulate_photometry(uvex) t_since_explosion = (phot["obs_time"] - event.t_explosion).to(u.day) t_theory = np.linspace(0, tde.duration_limit.to_value(u.day), 300) * u.day fig, ax = resolve_fig_axes(fig_size=(7, 4)) for band in ("FUV", "NUV"): plot_band_light_curve( ax, band, t_since_explosion, phot, t_theory=t_theory, theory_mag=event.mag(t_theory, uvex, band=band), snr_threshold=SNR_THRESHOLD, color=get_band_color(band), err_scale=5.0, label=band, ) ax.invert_yaxis() ax.set_xlabel("Days since explosion") ax.set_ylabel("AB magnitude") ax.set_title(f"Event {event.event_id} (z={event.redshift:.3f}, {event.n_observations} observations)") ax.legend() fig.tight_layout() plt.show() .. image-sg:: /auto_examples/simulating/images/sphx_glr_plot_tde_end_to_end_003.png :alt: Event 2844 (z=0.426, 4 observations) :srcset: /auto_examples/simulating/images/sphx_glr_plot_tde_end_to_end_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 11.268 seconds) .. _sphx_glr_download_auto_examples_simulating_plot_tde_end_to_end.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_tde_end_to_end.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_tde_end_to_end.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_tde_end_to_end.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_