Skip to content

Time Support And Reports

The convenience path constructs the event-anchored default support. Reports select from the completed result and cannot change the integration axis:

from datetime import date

import astropy.units as u
import numpy as np

from ecosys import EcosysEngine
from ecosys.domain.events import DepositionEvent
from ecosys.domain.landscape import Landscape
from ecosys.domain.populations import PopulationCohorts
from ecosys.domain.units import DOSE_UNIT
from ecosys.reporting import project_result

event_date = date(1986, 4, 29)
event = DepositionEvent.from_constant_air_concentration(
    "cs_137",
    event_date,
    300 * u.Bq / u.m**3,
    1 * u.day,
    16000 * u.Bq / u.m**2,
    4.5 * u.mm,
)
population = PopulationCohorts(
    np.array([20.0]) * u.year,
    np.array([1.0]) * u.dimensionless_unscaled,
)
result = EcosysEngine().run_default(
    (event,),
    population,
    output_start_date=event_date,
    horizon_years=1,
    landscape=Landscape("arable"),
)
report = project_result(
    result,
    (date(1986, 4, 30), date(1986, 5, 29)),
    labels=("day_1", "month_1"),
)

assert result.time_grid_kind == "default"
assert report.labels == ("day_1", "month_1")
report.selected_dates
report.per_capita_interval  # selected interval dose, still in Sv
report.per_capita_cumulative  # cumulative dose through each selected node
result.per_capita.interval.to_value(DOSE_UNIT) * 1000  # numeric mSv values

The low-level path accepts an explicit unit-bearing integration support. These points are the numerical support, not report-only samples:

from ecosys.domain.request import SimulationRequest

custom_request = SimulationRequest(
    (event,),
    np.array([0, 60, 120, 365]) * u.day,
    population,
    Landscape("arable"),
    output_start_date=event_date,
)
custom_result = EcosysEngine().integrate_on_grid(custom_request)
assert custom_result.time_grid_kind == "custom"
assert custom_result.times.value.tolist() == [0.0, 60.0, 120.0, 365.0]

The default and custom requests may produce different animal concentrations and dose values because support nodes advance model states and define dose intervals. For a per-capita array, interval[..., i, :] belongs to (t[i-1], t[i]], with the final axis indexing cohorts. The zero-time interval is zero except for event impulses from cloud inhalation and, when selected, cloud external exposure. Cumulative dose is the sum of intervals. A value reported at a one-year label is still a selected interval or cumulative dose in Sv, not an automatically annualized rate. Converting dose magnitudes from Sv to mSv multiplies by 1000.