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.