use crate::components::airglow;
use crate::evaluator::{ComponentMask, Observer, Target};
use crate::units::angular::Degrees;
use crate::units::radiometry::PhotonsPerSquareCentimeterNanosecondSteradian as BandPhotonRadiance;
use siderust::time::{Interval as TimePeriod, ModifiedJulianDate};
use std::sync::Arc;
use tempoch::{Period, UTC};
#[cfg_attr(
feature = "python",
pyo3::pyclass(frozen, module = "nsb", skip_from_py_object)
)]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ThresholdQuery {
pub observer: Observer,
pub target: Target,
pub window: Period<UTC>,
pub threshold: BandPhotonRadiance,
pub components: ComponentMask,
pub sun_altitude_ceiling: Option<Degrees>,
pub target_altitude_floor: Option<Degrees>,
}
impl ThresholdQuery {
pub const DEFAULT_SUN_ALTITUDE_CEILING: Degrees = Degrees::new(-18.0);
pub const DEFAULT_TARGET_ALTITUDE_FLOOR: Degrees = Degrees::new(0.0);
pub fn new(
observer: Observer,
target: Target,
window: Period<UTC>,
threshold: BandPhotonRadiance,
) -> Self {
Self {
observer,
target,
window,
threshold,
components: ComponentMask::ALL,
sun_altitude_ceiling: Some(Self::DEFAULT_SUN_ALTITUDE_CEILING),
target_altitude_floor: Some(Self::DEFAULT_TARGET_ALTITUDE_FLOOR),
}
}
pub fn with_components(mut self, components: ComponentMask) -> Self {
self.components = components;
self
}
pub fn with_sun_altitude_ceiling(mut self, sun_altitude_ceiling: Option<Degrees>) -> Self {
self.sun_altitude_ceiling = sun_altitude_ceiling;
self
}
pub fn with_target_altitude_floor(mut self, target_altitude_floor: Option<Degrees>) -> Self {
self.target_altitude_floor = target_altitude_floor;
self
}
}
#[derive(Clone)]
pub struct SiteWindowContext {
pub(crate) evaluator_identity: Arc<()>,
pub(crate) astronomy: Arc<super::astronomy::AstronomyCache>,
pub(crate) observer: Observer,
pub(crate) window: Period<UTC>,
pub(crate) components: ComponentMask,
pub(crate) sun_altitude_ceiling: Option<Degrees>,
pub(crate) tt_window: TimePeriod<ModifiedJulianDate>,
pub(crate) sun_filter_periods: Arc<[TimePeriod<ModifiedJulianDate>]>,
pub(crate) astronomical_night_periods: Arc<[airglow::temporal::AstronomicalNightPeriod]>,
pub(crate) airglow_phase_periods: Arc<[airglow::temporal::AirglowPhasePeriod]>,
pub(crate) airglow_model: Option<airglow::Airglow>,
pub(crate) solar_activity_cache: Option<crate::solar_activity::SolarActivityValueCache>,
pub(crate) moon_visible_periods: Option<Arc<[TimePeriod<ModifiedJulianDate>]>>,
}
impl std::fmt::Debug for SiteWindowContext {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter
.debug_struct("SiteWindowContext")
.field("observer", &self.observer)
.field("window", &self.window)
.field("components", &self.components)
.field("sun_altitude_ceiling", &self.sun_altitude_ceiling)
.field("sun_filter_periods", &self.sun_filter_periods.len())
.field(
"astronomical_night_periods",
&self.astronomical_night_periods.len(),
)
.field(
"moon_visible_periods",
&self.moon_visible_periods.as_ref().map(|p| p.len()),
)
.finish_non_exhaustive()
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ThresholdQueryResult {
pub threshold: BandPhotonRadiance,
pub periods: Vec<Period<UTC>>,
}
#[derive(Debug, Clone)]
pub(crate) struct PreparedThresholdQuery {
pub(crate) astronomy: Arc<super::astronomy::AstronomyCache>,
pub(crate) observer: Observer,
pub(crate) target: Target,
pub(crate) components: ComponentMask,
pub(crate) starlight_integrated: BandPhotonRadiance,
pub(crate) tt_window: TimePeriod<ModifiedJulianDate>,
pub(crate) astronomical_night_periods: Arc<[airglow::temporal::AstronomicalNightPeriod]>,
pub(crate) candidate_windows: Vec<TimePeriod<ModifiedJulianDate>>,
pub(crate) airglow_phase_periods: Arc<[airglow::temporal::AirglowPhasePeriod]>,
pub(crate) airglow_model: Option<airglow::Airglow>,
pub(crate) solar_activity_cache: Option<crate::solar_activity::SolarActivityValueCache>,
pub(crate) moon_visible_periods: Option<Arc<[TimePeriod<ModifiedJulianDate>]>>,
}