Skip to content

Commit f4c3fb2

Browse files
committed
Update plots module
- add plot_gammapy_sed add plot_irf_source_pointing Fix quotes formatting
1 parent 4234432 commit f4c3fb2

File tree

1 file changed

+138
-1
lines changed

1 file changed

+138
-1
lines changed

src/iact_estimator/plots.py

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
from pathlib import Path
55

66
import astropy.units as u
7+
from astropy.coordinates import AltAz
78
from astropy.visualization import quantity_support
8-
from astroplan import FixedTarget
9+
from astroplan import FixedTarget, time_grid_from_range
910
from astroplan.plots import plot_sky_24hr, plot_altitude
1011
import matplotlib.pyplot as plt
1112
import numpy as np
1213
import seaborn as sns
1314

15+
from gammapy.maps import MapAxis
16+
1417
from .core import observed_flux, get_horizon_stereo_profile
1518
from .spectral import crab_nebula_spectrum
1619
from iact_estimator import HORIZON_PROFILE_M1, HORIZON_PROFILE_M2
@@ -22,6 +25,8 @@
2225
"plot_altitude_airmass",
2326
"plot_exposure",
2427
"plot_rates",
28+
"plot_gammapy_sed",
29+
"plot_irf_source_pointing",
2530
]
2631

2732
logger = logging.getLogger(__name__)
@@ -404,3 +409,135 @@ def plot_rates(performance_data, title=None, ax=None):
404409
ax.set_xscale("log")
405410
ax.set_yscale("log")
406411
return ax
412+
413+
414+
def plot_gammapy_sed(
415+
observation_livetime,
416+
flux_points,
417+
assumed_spectral_model,
418+
plot_ts_profiles=True,
419+
energy_flux_unit="TeV cm-2 s-1",
420+
source_name=None,
421+
save=True,
422+
output_path=None,
423+
**kwargs,
424+
):
425+
"""Plot an SED with gammapy shoowing the significance per bin.
426+
427+
Optionally plot TS profiles.
428+
429+
Parameters
430+
==========
431+
observation_livetime : `astropy.units.Quantity`
432+
flux_points : `~gammapy.estimators.FluxPoints`
433+
assumed_spectral_model : `~gammapy.modeling.models.SpectralModel`
434+
plot_ts_profiles=True,
435+
energy_flux_unit : str, default="TeV cm-2 s-1"
436+
source_name : str, default=None
437+
savefig : bool, default=True
438+
output_path : str or `pathlib.Path`, default=None
439+
kwargs :
440+
Keyword arguments for `~matplotlib.axis.Axis.grid()`
441+
and `~matplotlib.figure.Figure.savefig()`.
442+
"""
443+
444+
grid_kwargs = kwargs.get("grid", {})
445+
savefig_kwargs = kwargs.get("savefig", {})
446+
seaborn_kwargs = kwargs.get("seaborn", {})
447+
448+
figsize = set_context_with_scaled_figsize(
449+
context=seaborn_kwargs["context"],
450+
base_figure_size=plt.rcParams["figure.figsize"],
451+
)
452+
fig, ax = plt.subplots(figsize=figsize, layout="constrained")
453+
454+
sed_type = "e2dnde"
455+
energy_flux_unit = u.Unit(energy_flux_unit)
456+
457+
ax.yaxis.units = energy_flux_unit
458+
459+
flux_points_table = flux_points.to_table(
460+
sed_type="e2dnde", format="gadf-sed", formatted=True
461+
)
462+
463+
energy_axis = MapAxis.from_energy_edges(
464+
np.concatenate(
465+
(
466+
flux_points_table["e_min"].data,
467+
np.array([flux_points_table["e_max"][-1]]),
468+
)
469+
)
470+
* flux_points_table["e_min"].unit
471+
)
472+
473+
assumed_spectral_model.plot(
474+
[energy_axis.edges.min().value, energy_axis.edges.max().value]
475+
* energy_axis.edges.unit,
476+
ax=ax,
477+
sed_type=sed_type,
478+
label="Assumed spectral model",
479+
color="green",
480+
)
481+
482+
flux_points.plot(
483+
ax=ax,
484+
sed_type=sed_type,
485+
color="darkorange",
486+
label=f"Estimated observation ({observation_livetime})",
487+
)
488+
489+
if plot_ts_profiles:
490+
flux_points.plot_ts_profiles(ax=ax, sed_type=sed_type, cmap="Blues")
491+
492+
for flux_point in flux_points_table:
493+
ax.annotate(
494+
rf"{flux_point['sqrt_ts']:.1f} $\sigma$",
495+
xy=(
496+
flux_point["e_min"],
497+
(
498+
flux_point["e2dnde"] * flux_point.table["e2dnde"].unit
499+
+ 3 * flux_point["e2dnde_err"] * flux_point.table["e2dnde_err"].unit
500+
).to_value(energy_flux_unit),
501+
),
502+
rotation=45,
503+
)
504+
505+
ax.grid(**grid_kwargs)
506+
507+
ax.set_ylabel(
508+
rf"$E^{2}\dfrac{{dN}}{{dE}}\quad$({energy_flux_unit.to_string('latex',fraction=False)})"
509+
)
510+
ax.legend()
511+
512+
if save:
513+
output_path = output_path if output_path is not None else Path.cwd()
514+
fig.savefig(
515+
output_path / f"{source_name or ''}_gammapy_sed.{savefig_kwargs['format']}",
516+
**savefig_kwargs,
517+
)
518+
519+
520+
def plot_irf_source_pointing(target_source, observation, ax=None, **kwargs):
521+
ax = plt.gca() if ax else None
522+
523+
observation_times = time_grid_from_range(
524+
[observation.tstart, observation.tstop], time_resolution=1 * u.h
525+
)
526+
527+
altaz_pointings = observation.get_pointing_altaz(observation_times)
528+
target_source_altaz = target_source.coord.transform_to(
529+
AltAz(
530+
obstime=observation_times, location=observation.observatory_earth_location
531+
)
532+
)
533+
534+
ax.plot(altaz_pointings.az, altaz_pointings.alt, label="IRFs pointing")
535+
ax.plot(target_source_altaz.az, target_source_altaz.alt, label="Target source")
536+
537+
ax.set_ylabel("Zenith angle (deg)")
538+
ax.set_xlabel("Azimuth angle (deg)")
539+
ax.grid()
540+
541+
ax.legend()
542+
543+
return ax

0 commit comments

Comments
 (0)