### Initialize new uv project and add sensipy Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Initializes a new Python project with a specified Python version (e.g., 3.12) using uv and then adds the sensipy package to it. This is useful for starting new projects. ```bash uv init -p 3.12 uv add sensipy ``` -------------------------------- ### Complete Sensipy Workflow Example (Python) Source: https://context7.com/astrojarred/sensipy/llms.txt Demonstrates a full sensipy workflow, starting from loading CTAO Instrument Response Functions (IRFs) and time-resolved source spectra, to visualizing spectral evolution. This example utilizes IRFHouse, Source, Sensitivity classes, and the get_data_path utility. It requires astropy, numpy, and matplotlib. ```python from sensipy.ctaoirf import IRFHouse from sensipy.source import Source from sensipy.sensitivity import Sensitivity from sensipy.util import get_data_path import astropy.units as u import numpy as np import matplotlib.pyplot as plt # 1. Load CTAO Instrument Response Functions house = IRFHouse(base_directory="./IRFs/CTAO") irf = house.get_irf( site="south", configuration="alpha", zenith=20, duration=1800, azimuth="average", version="prod5-v0.1", ) # 2. Load time-resolved source spectrum min_energy = 20 * u.GeV max_energy = 10 * u.TeV mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source( filepath=str(mock_data_path), min_energy=min_energy, max_energy=max_energy, ebl="franceschini", ) # 3. Visualize spectral pattern fig = source.show_spectral_pattern(return_plot=True) plt.title("Source Spectral Evolution") plt.savefig("spectral_pattern.png") ``` -------------------------------- ### Verify sensipy setup with Python Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/setup.mdx This Python script verifies the sensipy setup by testing the loading of CTAO IRFs and spectral models. It utilizes the `sensipy.ctaoirf.IRFHouse` and `sensipy.source.Source` classes, along with `astropy.units`. Ensure IRFs are downloaded to './IRFs/CTAO' and mock data is accessible. ```python from sensipy.ctaoirf import IRFHouse from sensipy.source import Source import astropy.units as u # Test IRF loading print("Testing IRF loading...") try: house = IRFHouse(base_directory="./IRFs/CTAO") irf = house.get_irf( site="south", configuration="alpha", zenith=20, duration=1800, azimuth="average", version="prod5-v0.1", ) print("✓ IRF loading successful") except Exception as e: print(f"✗ IRF loading failed: {e}") # Test spectral model loading print("Testing spectral model loading with EBL...") try: from sensipy.util import get_data_path mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source( filepath=str(mock_data_path), min_energy=30 * u.GeV, max_energy=10 * u.TeV, ebl="franceschini", ) print("✓ Spectral model loading successful") except Exception as e: print(f"✗ Spectral model loading failed: {e}") ``` -------------------------------- ### Run sensipy test suite with uv Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Runs the test suite for sensipy after cloning the repository, using uv to manage the execution environment. This is typically done for development purposes. ```bash git clone https://github.com/astrojarred/sensipy.git cd sensipy uv run pytest ``` -------------------------------- ### Verify sensipy installation Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Verifies that the sensipy package has been installed correctly by importing it and printing its version. This command can be run directly from the command line. ```python python -c "import sensipy; print(sensipy.__version__)" ``` -------------------------------- ### Setup IRF, Define Source, and Calculate Sensitivity Curve Source: https://context7.com/astrojarred/sensipy/llms.txt This snippet demonstrates the initial setup for sensitivity calculations in Sensipy. It involves loading an IRF (Instrument Response Function) using IRFHouse, defining a source with its spectral properties, and then creating a Sensitivity object. Finally, it computes the sensitivity curve for the defined source. ```python from sensipy.sensitivity import Sensitivity from sensipy.ctaoirf import IRFHouse from sensipy.util import get_data_path import astropy.units as u # Setup: Load IRF and source house = IRFHouse(base_directory="./IRFs/CTAO") irf = house.get_irf( site="south", configuration="alpha", zenith=20, duration=1800, azimuth="average", version="prod5-v0.1", ) mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, ebl="franceschini" ) # Create sensitivity calculator sensitivity = Sensitivity( irf=irf, observatory="ctao_south", # Observatory location for gammapy min_energy=20 * u.GeV, max_energy=10 * u.TeV, radius=3.0 * u.deg, # Region of interest radius min_time=1 * u.s, # Minimum observation time max_time=43200 * u.s, # Maximum observation time (12 hours) n_sensitivity_points=16, # Number of time points to calculate ebl="franceschini", # Apply EBL when calculating sensitivity ) # Compute sensitivity curve for the source sensitivity.get_sensitivity_curve(source=source) # Access the computed curves print(f"Sensitivity curve: {sensitivity.sensitivity_curve}") print(f"Photon flux curve: {sensitivity.photon_flux_curve}") # Query sensitivity at arbitrary times (via interpolation) sens_at_1000s = sensitivity.get(t=1000 * u.s, mode="sensitivity") flux_at_1000s = sensitivity.get(t=1000 * u.s, mode="photon_flux") print(f"Sensitivity at 1000s: {sens_at_1000s}") print(f"Photon flux at 1000s: {flux_at_1000s}") # Get sensitivity information as table table = sensitivity.table() df = sensitivity.pandas() ``` -------------------------------- ### Simulate Source Detection with Sensipy Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/exposure.mdx Demonstrates the basic workflow for setting up an IRF house, defining a source with specific energy ranges, and performing a detection simulation. It checks if a source is detectable at a given start time and outputs the observation result. ```python import astropy.units as u from sensipy.source import Source from sensipy.sensitivity import Sensitivity from sensipy.ctaoirf import IRFHouse # Setup house = IRFHouse(base_directory="./IRFs/CTAO") irf = house.get_irf( site="south", configuration="alpha", zenith=20, duration=1800, azimuth="average", version="prod5-v0.1", ) from sensipy.util import get_data_path mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") # Define energy range (typical for CTA) min_energy = 20 * u.GeV max_energy = 10 * u.TeV source = Source( filepath=str(mock_data_path), min_energy=min_energy, max_energy=max_energy, ebl="franceschini" ) sens = Sensitivity( irf=irf, observatory="ctao_south", min_energy=min_energy, max_energy=max_energy, radius=3.0 * u.deg, ) sens.get_sensitivity_curve(source=source) # Observe starting 30 minutes after event result = source.observe( sensitivity=sens, start_time=30 * u.min, min_energy=min_energy, max_energy=max_energy, ) if result['seen']: print(f"✓ Detectable in {result['obs_time']}") else: print(f"✗ Not detectable: {result['error_message']}") ``` -------------------------------- ### Run sensipy test suite with pytest Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Executes the sensipy test suite using pytest. This command assumes you are in a cloned repository with development dependencies installed, or within a suitable virtual/conda environment. ```bash pytest ``` -------------------------------- ### Install sensipy with pip Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Installs the sensipy package into any existing Python environment using pip. This is a standard method for installing Python packages. ```bash pip install sensipy ``` -------------------------------- ### Generate and Customize Detectability Heatmaps Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/detectability.mdx Illustrates how to visualize detectability data using heatmaps. Includes examples for basic plotting, advanced customization of visual parameters, and dynamic title generation. ```python import matplotlib.pyplot as plt import numpy as np data.set_observation_times(np.logspace(1, np.log10(3600), 10, dtype=int)) data.plot( title="Custom Detectability Plot", max_exposure=2, as_percent=True, color_scheme="viridis", color_scale="log", annotate=True ) ``` -------------------------------- ### Download CTAO IRFs using sensipy CLI Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/setup.mdx This command-line interface (CLI) command downloads the necessary CTAO Instrument Response Functions (IRFs) to a specified directory. It requires the sensipy package to be installed and an activated conda environment for the second syntax. ```bash uv run sensipy-download-ctao-irfs ``` ```bash sensipy-download-ctao-irfs ``` -------------------------------- ### Install sensipy in conda environment Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Installs the sensipy package into a conda environment. This process involves activating the environment, ensuring pip is installed, and then using pip to install sensipy. ```bash conda activate my-environment conda install pip pip install sensipy ``` -------------------------------- ### Add sensipy to uv project Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Adds the sensipy package to an existing uv-managed Python project. This command assumes you have uv installed and are in the project's root directory. ```bash uv add sensipy ``` -------------------------------- ### Query spectrum and flux at specific times and energies (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Provides examples of querying the spectral model for flux at specific times and energies using the get_spectrum and get_flux methods. It utilizes astropy units for time and energy. ```python import astropy.units as u # Get spectrum at a specific time time = 100 * u.s spectrum = source.get_spectrum(time=time) # Get flux at a specific energy and time energy = 1 * u.TeV flux = source.get_flux(energy=energy, time=time) # Get lightcurve at a specific energy lightcurve = source.get_flux(energy=energy) ``` -------------------------------- ### Update sensipy package with uv Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/getting_started/installation.mdx Updates the sensipy package to its latest version within a uv-managed project. The '-U' flag ensures the package is upgraded. ```bash uv add -U sensipy ``` -------------------------------- ### Specify Energy Range for Spectral Models (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Demonstrates how to specify the minimum and maximum energy when loading spectral models. This is crucial for optimizing performance, matching observatory capabilities, and ensuring correct EBL absorption. Uses typical CTA energy ranges as an example. ```python # Typical CTA energy range min_energy = 20 * u.GeV # or 0.02 TeV max_energy = 10 * u.TeV source = Source( filepath="path/to/model.csv", min_energy=min_energy, max_energy=max_energy, ) ``` -------------------------------- ### Download CTAO IRFs using sensipy Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/irfs.mdx This command-line interface (CLI) tool automates the download and organization of CTAO IRFs. It requires sensipy to be installed. The tool downloads IRFs to a specified directory, typically './IRFs/CTAO'. For more options, consult the help message. ```bash uv run sensipy-download-ctao-irfs ``` ```bash pip install sensipy sensipy-download-ctao-irfs ``` ```bash conda activate my-environment sensipy-download-ctao-irfs ``` -------------------------------- ### Load FITS Spectral Model - Python Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Loads a spectral model from a FITS file using the Sensipy Source class. This method requires specifying the file path and can include EBL absorption parameters. The example shows how to load a FITS file with EBL correction. ```python from sensipy.source import Source from sensipy.util import get_data_path import astropy.units as u # Get path to package mock data mock_fits_path = get_data_path("mock_data/GRB_42_mock.fits") # Load FITS spectral model source = Source( filepath=str(mock_fits_path), min_energy=30 * u.GeV, max_energy=10 * u.TeV, ebl="dominguez", z=0.5, ) ``` -------------------------------- ### Load and Configure EBL Models in Python Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/ebl_models.mdx Demonstrates how to initialize a source with a specific EBL model, dynamically update the model and redshift, and remove absorption settings. These methods allow for flexible spectral analysis of extragalactic sources. ```python from sensipy.source import Source from sensipy.util import get_data_path import astropy.units as u # Get path to package mock data mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") # Load source with EBL absorption source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=1 * u.TeV, ebl="franceschini" # Apply Franceschini 2008 model ) # Update or override EBL model and redshift source.set_ebl_model(ebl="dominguez", z=0.5) # Remove EBL absorption source.set_ebl_model(ebl=None) ``` -------------------------------- ### Visualize spectral pattern (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Demonstrates how to visualize the full time-energy spectral pattern using the show_spectral_pattern method, allowing for adjustable grid resolution. ```python # Show the full time-energy spectral pattern source.show_spectral_pattern( resolution=100, # Grid resolution return_plot=True ) ``` -------------------------------- ### Initializing lookup table generation Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/followups.mdx Sets up the necessary IRFHouse and configuration grids required to generate custom lookup tables for specific catalogs. ```python from sensipy.ctaoirf import IRFHouse import astropy.units as u house = IRFHouse(base_directory="./IRFs/CTAO") sites = ["north", "south"] zeniths = [20, 40, 60] delays = [10, 30, 100, 300, 1000, 3000] * u.s ebl_models = [None, "franceschini"] ``` -------------------------------- ### Load Detectability Data with Sensipy Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/detectability.mdx Demonstrates how to initialize the LookupData class to load detectability data from a file. This process is essential for performing subsequent filtering and visualization tasks. ```python from sensipy.detectability import LookupData from sensipy.data.create_mock_lookup import create_mock_lookup_table from pathlib import Path import tempfile with tempfile.TemporaryDirectory() as tmpdir: lookup_path = create_mock_lookup_table( event_ids=[1, 2, 3, 4, 5], sites=["north", "south"], zeniths=[20, 40, 60], delays=[10, 30, 100, 300, 1000, 3000, 10000], output_dir=tmpdir, ) data = LookupData(lookup_path) print(f"Loaded {len(data)} rows") ``` -------------------------------- ### Create Comparative Heatmap Grids Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/detectability.mdx Uses create_heatmap_grid to visualize multiple configuration datasets side-by-side. This is useful for comparing different site and zenith angle parameters. ```python from sensipy.detectability import create_heatmap_grid data_north_z20 = LookupData(lookup_path) data_north_z20.set_filters(("irf_site", "==", "north"), ("irf_zenith", "==", 20)) data_north_z40 = LookupData(lookup_path) data_north_z40.set_filters(("irf_site", "==", "north"), ("irf_zenith", "==", 40)) data_south_z20 = LookupData(lookup_path) data_south_z20.set_filters(("irf_site", "==", "south"), ("irf_zenith", "==", 20)) data_south_z40 = LookupData(lookup_path) data_south_z40.set_filters(("irf_site", "==", "south"), ("irf_zenith", "==", 40)) fig, axes = create_heatmap_grid( [data_north_z20, data_north_z40, data_south_z20, data_south_z40], grid_size=(2, 2), max_exposure=1, title="Detectability Comparison: Site and Zenith Configurations", subtitles=["North, z20", "North, z40", "South, z20", "South, z40"], cmap="mako", ) plt.savefig("detectability_grid.png", dpi=150, bbox_inches="tight") plt.close() ``` -------------------------------- ### Calculate Significance Evolution (Python) Source: https://context7.com/astrojarred/sensipy/llms.txt Calculates the evolution of detection significance over time for a given source. It requires a Sensitivity object and specifies start and maximum observation times, along with the number of time steps. ```python end_times, significances = source.get_significance_evolution( sensitivity=sensitivity, start_time=100 * u.s, max_time=2 * u.hour, n_time_steps=30, ) ``` -------------------------------- ### Export Template Spectrum to Gammapy (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Shows how to export the full energy spectrum of a Sensipy Source at a given time as a Gammapy ScaledTemplateModel. This preserves the detailed spectral shape, which is beneficial when a power-law approximation is insufficient. ```python from sensipy.source import Source from sensipy.util import get_data_path import astropy.units as u mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, ) time = 100 * u.s template_model = source.get_template_spectrum(time, scaling_factor=1.0) # Template models preserve the full spectral shape # Useful when power law approximation is insufficient ``` -------------------------------- ### Initialize Sensitivity Calculator with sensipy Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/sensitivity.mdx Demonstrates how to load Instrument Response Functions (IRFs) using IRFHouse and configure the Sensitivity class to calculate observatory detection limits. It requires defining the observatory site, energy range, and spatial extraction radius. ```python from sensipy.ctaoirf import IRFHouse from sensipy.sensitivity import Sensitivity import astropy.units as u # Load IRFs house = IRFHouse(base_directory="./IRFs/CTAO") irf = house.get_irf( site="south", configuration="alpha", zenith=20, duration=1800, # seconds azimuth="average", version="prod5-v0.1", ) # Create sensitivity calculator sensitivity = Sensitivity( irf=irf, observatory=f"ctao_{irf.site.name}", # "ctao_south" min_energy=20 * u.GeV, max_energy=10 * u.TeV, radius=3.0 * u.deg, # Region of interest radius ) ``` -------------------------------- ### Get Sensitivity at Specific Time (Differential and Photon Flux) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/sensitivity.mdx Retrieves the differential sensitivity and photon flux sensitivity at a given time. This is useful for understanding the instrument's sensitivity to different types of signals at a particular observation duration. ```python from astropy import units as u # Assuming 'sens' is an initialized Sensitivity object time = 1000 * u.s diff_sens = sens.get(time, mode="sensitivity") phot_flux = sens.get(time, mode="photon_flux") print(f"At t={time}:") print(f" Differential sensitivity: {diff_sens}") print(f" Photon flux sensitivity: {phot_flux}") ``` -------------------------------- ### Load Custom Spectral Models (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Illustrates how to load custom spectral models from local CSV or FITS files into a Sensipy Source object. Includes optional parameters for EBL absorption and redshift. ```python from sensipy.source import Source import astropy.units as u # Load your custom spectral model source = Source( filepath="path/to/your/model.csv", min_energy=30 * u.GeV, max_energy=10 * u.TeV, ebl="franceschini", # Optional: add EBL absorption for extragalactic sources z=0.5, ) ``` -------------------------------- ### Configure Custom Column Names Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/detectability.mdx Explains how to map non-standard column names in your source files to the expected format required by the LookupData class. ```python data = LookupData( "my_lookup_table.parquet", delay_column="delay_col", obs_time_column="time_col", ) ``` -------------------------------- ### Sensipy Function Return Value Example (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/followups.mdx Illustrates the structure of the dictionary returned by Sensipy functions, including observation time, detection status, energy range, and optional metadata columns from a lookup table. It also shows fields for error messages. ```python { 'obs_time': , 'seen': bool, 'start_time': , 'end_time': , 'ebl_model': str, 'min_energy': , 'max_energy': , 'long': , 'lat': , 'dist': , 'id': int, 'error_message': str } ``` -------------------------------- ### Calculate Exposure Time with Sensipy Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/exposure.mdx Calculates the required observation time for a gamma-ray source to reach a target significance. It requires a `Sensitivity` object, observation start time, and energy range. It returns the observation time, detection status, and start/end times. ```python from sensipy.source import Source from sensipy.sensitivity import Sensitivity from sensipy.ctaoirf import IRFHouse from sensipy.util import get_data_path import astropy.units as u # Load IRFs house = IRFHouse(base_directory="./IRFs/CTAO") irf = house.get_irf( site="south", configuration="alpha", zenith=20, duration=1800, azimuth="average", version="prod5-v0.1", ) # Load source mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") # Define energy range (typical for CTA) min_energy = 20 * u.GeV max_energy = 10 * u.TeV source = Source( filepath=str(mock_data_path), min_energy=min_energy, max_energy=max_energy, ebl="franceschini" ) # Create sensitivity calculator sens = Sensitivity( irf=irf, observatory="ctao_south", min_energy=min_energy, max_energy=max_energy, radius=3.0 * u.deg, ) sens.get_sensitivity_curve(source=source) # Simulate observation starting 30 minutes after event result = source.observe( sensitivity=sens, start_time=30 * u.min, min_energy=min_energy, max_energy=max_energy, ) print(f"Required observation time: {result['obs_time']}") print(f"Detection achieved: {result['seen']}") print(f"Start time: {result['start_time']}") print(f"End time: {result['end_time']}") ``` -------------------------------- ### Access metadata via dictionary (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Demonstrates accessing the full metadata dictionary from a loaded Source object and retrieving specific metadata values using the .get() method. ```python # Access the full metadata dictionary meta = source.metadata print(f"All metadata keys: {list(meta.keys())}") print(f"Event ID: {meta.get('event_id')}") print(f"Distance: {meta.get('distance')}") ``` -------------------------------- ### Load and Inspect Lookup Table - Python Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/followups.mdx Demonstrates how to load a pre-computed lookup table using pandas and inspect its columns. This is a foundational step for using the followup module, as it requires a structured table containing observation data. ```python import pandas as pd from sensipy.util import get_data_path # Load lookup table (sample data included with sensipy) lookup_path = get_data_path("mock_data/sample_lookup_table.parquet") df = pd.read_parquet(lookup_path) print(df.columns) ``` -------------------------------- ### Apply EBL Absorption to Power Law Spectrum (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Demonstrates how to automatically apply EBL absorption to a power law spectrum using the 'use_ebl=True' parameter. Requires a Source object with EBL model specified and a time duration. Outputs the power law spectrum with EBL absorption. ```python source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, z=1.0, ebl="franceschini", # Set EBL model ) time = 100 * u.s # Apply EBL absorption automatically (or use default: use_ebl=None) powerlaw_with_ebl = source.get_powerlaw_spectrum(time, use_ebl=True) ``` -------------------------------- ### Configure Gammapy EBL Datasets Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/ebl_models.mdx Provides the shell commands required to set up the environment and download external EBL datasets compatible with the sensipy framework. ```bash export GAMMAPY_DATA=/path/to/gammapy-data gammapy download datasets ``` -------------------------------- ### Configure Sensitivity Modes Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/exposure.mdx Demonstrates how to switch between integral sensitivity and photon flux modes during the observation simulation process. ```python # Use photon flux mode # Assume source and sens are already set up with min_energy = 20 * u.GeV result = source.observe( sensitivity=sens, start_time=30 * u.min, min_energy=min_energy, max_energy=max_energy, sensitivity_mode="photon_flux", # Use photon flux ) ``` -------------------------------- ### Perform Basic Followup Queries in Python Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/followups.mdx Demonstrates how to query event exposure using the sensipy.followup module. It covers single event lookups, batch processing for multiple events, and scanning delay parameters to visualize detectability. ```python from sensipy import followup from sensipy.util import get_data_path import astropy.units as u import pandas as pd lookup_path = get_data_path("mock_data/sample_lookup_table.parquet") lookup_df = pd.read_parquet(lookup_path) result = followup.get_exposure( delay=30 * u.min, lookup_df=lookup_df, event_id=1, irf_site="south", irf_zenith=20, irf_ebl_model="franceschini", ) if result['seen']: print(f"Event 1 detectable in {result['obs_time']}") ``` ```python for event_id in [1, 2, 3, 4, 5]: result = followup.get_exposure( delay=10 * u.s, lookup_df=lookup_df, event_id=event_id, irf_site="north", irf_zenith=40, irf_ebl_model="franceschini", ) ``` ```python import numpy as np import matplotlib.pyplot as plt delays = np.logspace(1, 4, 30) * u.s obs_times = [] for delay in delays: result = followup.get_exposure(delay=delay, lookup_df=lookup_df, event_id=4, irf_site="south", irf_zenith=20, irf_ebl_model="franceschini") obs_times.append(result['obs_time'].to(u.s).value if result['seen'] else np.nan) plt.loglog(delays.value, obs_times, 'o-') plt.show() ``` -------------------------------- ### Apply EBL Absorption to Template Spectrum (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Shows how to automatically apply EBL absorption to a template spectrum using the 'use_ebl=True' parameter. This requires a Source object with an EBL model defined and a specified time. The output is the template spectrum with EBL absorption applied. ```python source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, z=1.0, ebl="franceschini", # Set EBL model ) time = 100 * u.s # Apply EBL absorption automatically (or use default: use_ebl=None) template_with_ebl = source.get_template_spectrum(time, use_ebl=True) ``` -------------------------------- ### Scale Spectral Templates with ScaledTemplateModel Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/sensitivity.mdx Demonstrates how to initialize a ScaledTemplateModel using a Gammapy TemplateSpectralModel. This utility allows for dynamic adjustment of flux normalization via a scaling factor, which is primarily used internally by the sensitivity calculator. ```python from sensipy.sensitivity import ScaledTemplateModel from gammapy.modeling.models import TemplateSpectralModel import astropy.units as u import numpy as np # Create a template spectral model with energy and flux values energy = np.logspace(-1, 2, 10) * u.TeV # 0.1 to 100 TeV values = np.ones(10) * u.Unit("1 / (TeV s cm2)") # Constant flux template_model = TemplateSpectralModel(energy=energy, values=values) # Create a scaled template from the Gammapy model scaled_model = ScaledTemplateModel.from_template( model=template_model, scaling_factor=1e-6 # Scale down initial normalization ) # The scaling factor can be adjusted scaled_model.scaling_factor = 0.5 # Reduce flux by 50% ``` -------------------------------- ### Create Sensitivity Calculator and Compute Curve (Python) Source: https://context7.com/astrojarred/sensipy/llms.txt Initializes a Sensitivity object with observatory parameters and computes the sensitivity curve for a given source. Requires gammapy IRF data and astropy units. ```python sensitivity = Sensitivity( irf=irf, observatory="ctao_south", min_energy=min_energy, max_energy=max_energy, radius=3.0 * u.deg, n_sensitivity_points=20, ) sensitivity.get_sensitivity_curve(source=source) ``` -------------------------------- ### Analyze detection results and scan delays in Python Source: https://context7.com/astrojarred/sensipy/llms.txt Demonstrates how to interpret detection results from a source observation and iterate over multiple delay times to determine detectability. It uses numpy for logarithmic spacing of time intervals and checks the 'seen' status of the observation. ```python if result['seen']: print(f"Detection possible!") print(f"Required observation time: {result['obs_time']}") print(f"Observation starts at: {result['start_time']}") print(f"Detection achieved at: {result['end_time']}") else: print(f"Not detectable: {result.get('error_message', 'Unknown reason')}") import numpy as np delays = np.logspace(1, 4, 10) * u.s for delay in delays: result = source.observe(sensitivity=sens, start_time=delay, min_energy=min_energy, max_energy=max_energy) if result['seen']: print(f"Delay {delay}: detectable in {result['obs_time']}") else: print(f"Delay {delay}: not detectable") ``` -------------------------------- ### Set Distance During Source Initialization (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Demonstrates initializing a Sensipy Source object with either redshift (z) or an astropy Distance object for EBL absorption calculations. Ensures correct EBL correction for extragalactic sources. ```python from sensipy.source import Source from sensipy.util import get_data_path import astropy.units as u mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") # Set redshift during initialization source_z = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, z=0.5, # Redshift ebl="franceschini", ) # Set distance during initialization from astropy.coordinates import Distance distance = Distance(3000 * u.Mpc) source_dist = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, distance=distance, # Distance object ebl="franceschini", ) ``` -------------------------------- ### Load and Interpolate Time-Resolved Spectra with Source Source: https://context7.com/astrojarred/sensipy/llms.txt The Source class processes time-energy spectra from FITS, CSV, or text files. It supports EBL absorption models and provides methods to retrieve spectral indices, template models, and power-law fits for specific time intervals. ```python from sensipy.source import Source from sensipy.util import get_data_path import astropy.units as u # Load source from CSV file mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, ebl="franceschini", ) # Get spectrum and spectral index at a specific time spectrum = source.get_spectrum(time=100 * u.s) index = source.get_spectral_index(time=100 * u.s) # Get template spectrum model for gammapy template_model = source.get_template_spectrum(time=100 * u.s) template_model.plot() ``` -------------------------------- ### Load FITS file and access metadata via attributes (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Loads a FITS file using the Source class and demonstrates accessing metadata like event ID, longitude, latitude, and distance using attribute notation. It highlights that only keys present in the metadata file are available. ```python from sensipy.source import Source from sensipy.util import get_data_path # Load FITS file with flexible metadata mock_fits_path = get_data_path("mock_data/GRB_42_mock.fits") source = Source(mock_fits_path) # Access metadata via attribute notation print(f"Event ID: {source.event_id}") # 42 print(f"Longitude: {source.longitude}") # 0.0 rad print(f"Latitude: {source.latitude}") # 1.0 rad print(f"Distance: {source.distance}") # 100000.0 kpc (Distance object) ``` ```python from sensipy.source import Source from sensipy.util import get_data_path mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source(filepath=str(mock_data_path)) # Access metadata via attributes (using keys from your metadata file) print(f"Event ID: {source.event_id}") print(f"Distance: {source.distance}") print(f"Coordinates: RA={source.longitude}, Dec={source.latitude}") # Note: Only keys present in your metadata file are available # The example above uses keys from the mock data (event_id, longitude, latitude, distance) ``` -------------------------------- ### Load and Process Event Catalog Data Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/followups.mdx This Python code snippet loads event catalog files, iterates through various simulation parameters (site, zenith, EBL model, delay), calculates source sensitivity using IRF and source definitions, and simulates observations. It collects results into a list and saves them to a Parquet file. ```python event_files = list(Path("./catalog/").glob("*.fits")) results = [] for event_file in event_files: for site in sites: for zenith in zeniths: for ebl in ebl_models: # Load IRF irf = house.get_irf( site=site, configuration="alpha", zenith=zenith, duration=1800, azimuth="average", version="prod5-v0.1", ) # Load source source = Source( filepath=str(event_file), min_energy=20 * u.GeV, max_energy=10 * u.TeV, ebl=ebl ) # Calculate sensitivity sens = Sensitivity( irf=irf, observatory=f"ctao_{site}", min_energy=20 * u.GeV, max_energy=10 * u.TeV, radius=3.0 * u.deg, ) sens.get_sensitivity_curve(source=source) # Simulate at each delay for delay in delays: result = source.observe( sensitivity=sens, start_time=delay, min_energy=20 * u.GeV, max_energy=10 * u.TeV, ) # Add configuration info result['site'] = site result['zenith'] = zenith result['delay'] = delay.to(u.s).value result['ebl'] = ebl if ebl else "none" results.append(result) # Save to Parquet df = pd.DataFrame(results) df.to_parquet("my_lookup_table.parquet") ``` -------------------------------- ### Explore Parameter Space for Event Detection Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/followups.mdx Calculates detection fractions across different observation sites and zenith angles. This approach iterates through a subset of events to build a detection matrix. ```python import numpy as np from sensipy import followup event_ids = lookup_df['event_id'].unique()[:100] sites = ["north", "south"] zeniths = [20, 40, 60] detection_matrix = np.zeros((len(sites), len(zeniths))) for i, site in enumerate(sites): for j, zenith in enumerate(zeniths): detections = sum(1 for eid in event_ids if followup.get_exposure(delay=60*u.s, lookup_df=lookup_df, event_id=eid, irf_site=site, irf_zenith=zenith, irf_ebl_model="franceschini")['seen']) detection_matrix[i, j] = detections / len(event_ids) ``` -------------------------------- ### Load Source and Compute Sensitivity Curve Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/sensitivity.mdx Loads mock data, defines a source object, and initializes a sensitivity calculator to compute the sensitivity curve. This involves specifying source properties like energy range and EBL model, and observatory parameters. ```python from astropy import units as u from sensipy.sensitivity import Sensitivity from sensipy.utils import get_data_path from sensipy.source import Source # Load IRFs (assuming 'irf' is already defined and loaded) irf = None # Placeholder for actual IRF loading mock_data_path = get_data_path("mock_data/GRB_42_mock.csv") source = Source( filepath=str(mock_data_path), min_energy=20 * u.GeV, max_energy=10 * u.TeV, ebl="franceschini" ) sens = Sensitivity( irf=irf, observatory="ctao_south", min_energy=20 * u.GeV, max_energy=10 * u.TeV, radius=3.0 * u.deg, ) sens.get_sensitivity_curve(source=source) ``` -------------------------------- ### Plot Spectral Model with Automatic Energy Range (Python) Source: https://github.com/astrojarred/sensipy/blob/main/docs/src/content/docs/working_with_sensipy/spectral_models.mdx Illustrates how to plot a spectral model using its overridden .plot() method, which automatically utilizes the source's min_energy and max_energy. It also shows how to manually override the energy range for plotting if needed. ```python # Plot automatically uses source.min_energy and source.max_energy powerlaw_model.plot() # You can still override the energy range if needed powerlaw_model.plot(energy_range=(0.1 * u.TeV, 5 * u.TeV)) ```